Python Socket Library, Errno 10054 When Client Quits
所以我正在搞乱一个非常简单的echo服务器/客户端的交易。我最终将要制作游戏服务器,但是现在我只是想设置基本部分。
这是服务器:http://pastebin.com/qtfrMGur
这是客户端:http://pastebin.com/3VK3VxPX
所以,我的问题是,当客户端断开连接时,我得到socket.error:[Errno 10054]远程主机强行关闭现有连接。当可读套接字列表没有待处理信息时,我认为select.select()返回false(或空列表,无论如何)。这似乎是错误的原因,但是如果客户端不再存在,为什么select.select()返回true(第26行)?当我尝试检索第27行中的某些信息时发生实际错误。我真的很困惑,假设套接字的客户端已关闭,不应该只返回[],然后转到其他地方第31行并销毁该客户?
我真的不知道还有什么要发布,这看起来像是一个非常基本的问题,通常我使用一个更加抽象的库,如扭曲,这使得它很容易,但对于这个项目,我必须使用传统的BSD套接字。如果你们有任何其他信息,你只需要问。
谢谢。
编辑:所以我在那里放了一个print语句来打印select.select(...)[0]的值,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | for cl in clients: ready = select.select([cl], [], [], .1)[0] print ready if ready: data = cl.recv(size) if data: print data #cl.send(data) else: print"Client Quit " clients.remove(cl) cl.shutdown(socket.SHUT_RDWR) cl.close() print len(clients) |
如你所见,我现在也正确关机。问题是,当客户端退出时,select.select(...)将客户端套接字作为可读源返回,因此cl.recv被调用,然后抛出错误,因为cl在另一端关闭。至少这是我的怀疑。
那么,有人可以解释一下我在这里做错了什么吗?为什么客户端发送最后一条死亡消息,是否应该利用某种功能?
谢谢
EDIT2:所以大家我启动了我的debian机器,代码运行完美,它只在Windows中才能正常运行。这是某种错误吗?我的印象是套接字库抽象了引擎盖下的所有东西,使得OS之间的界面相同。
你应该在客户端关闭它之前调用套接字的
1 2 | s.shutdown(socket.SHUT_RDWR) s.close() |
这样它就不允许进一步发送/接收,查看有关它的Python文档,它在那里得到了很好的解释。
更新:修复客户端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import socket host = 'localhost' port = 50000 size = 1024 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host,port)) msg = '' while msg !='quit': msg = raw_input() s.send(msg) #data = s.recv(size) s.shutdown(socket.SHUT_RDWR) s.close() |