【发布时间】:2013-05-01 06:13:39
【问题描述】:
所以我在搞一个非常简单的回显服务器/客户端类型的交易。我最终会做一个游戏服务器,但现在我只是尝试设置基本部分。
这里是服务器:http://pastebin.com/qtfrMGur
这是客户:http://pastebin.com/3VK3VxPX
所以,我的问题是,当客户端断开连接时,我得到 socket.error: [Errno 10054] 现有连接被远程主机强行关闭。我的印象是,当可读的套接字列表没有待处理的信息时,select.select() 返回 false(或空列表,等等)。这似乎是错误的原因,但是如果客户端不再存在,为什么 select.select() 返回 true(在第 26 行)?当我尝试在第 27 行检索一些信息时发生实际错误。我对此感到非常困惑,假设套接字的客户端已关闭,它不应该只是返回 [],然后转到 else on第 31 行并销毁该客户端?
我真的不知道还要发布什么,这似乎是一个非常基本的问题,通常我使用更抽象的库,比如 twisted,这很容易,但是对于这个项目,我必须使用传统的 BSD 套接字。如果你们有任何其他需要的信息,请尽管询问。
谢谢。
编辑:所以我在其中放了一条打印语句来打印 select.select(...)[0] 的值,如下所示:
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\n"
clients.remove(cl)
cl.shutdown(socket.SHUT_RDWR)
cl.close()
print len(clients)
如您所见,我现在也进行了适当的关机。问题是,当客户端退出时, select.select(...) 将客户端套接字作为可读源返回,因此 cl.recv 被调用,然后抛出错误,因为 cl 在另一端关闭.至少这是我的怀疑。
那么,有人可以解释一下我在这里可能做错了什么吗?为什么客户端会发送最后一条死亡消息,这是我应该利用的某种功能吗?
谢谢
EDIT2:所以伙计们,我启动了我的 debian 机器,代码完美运行,只有在 Windows 中它才会这样做。这是某种错误吗?我的印象是套接字库抽象了引擎盖下的所有东西,以使操作系统之间的接口相同。
【问题讨论】:
-
只是一个想法,但也许这是一个竞争条件。
recv可以返回一个客户端,同时该客户端可能会断开连接。不过看起来你一定很倒霉。 -
我不认为这是一个竞争条件,我在那里打印了一些打印来诊断问题,似乎 select.select() 在客户端退出时正在返回客户端套接字。就好像客户端有一些最后的消息功能,当它死时它会发送一些信息。
标签: python sockets client host errno