客户端退出时,Python套接字库,Errno 10054

时间:2013-04-30 02:56:23

标签: python sockets client host errno

所以我正在搞乱一个非常简单的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]的值,如下所示:

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中才会这样做。这是某种错误吗?我的印象是套接字库抽象了引擎盖下的所有内容,使得操作系统之间的界面相同。

1 个答案:

答案 0 :(得分:1)

在客户端关闭套接字之前,你应该调用套接字的shutdown方法,如下所示:

s.shutdown(socket.SHUT_RDWR)
s.close()

这样它就不允许进一步发送/接收,查看有关它的Python文档,在那里很好地解释了。

更新:修复客户端代码

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()