Python关闭TCP连接

4
我有一个Python TCP服务器,每个连接都有一个线程进行监听。当我在连接对象上调用`close`时,会抛出“bad file descriptor”异常。通过谷歌搜索,我发现了一些解决方案,每个解决方案都使用循环接收客户端数据并在决定断开客户端时中断该循环。我的客户端是用C#编写的,并且不知道它已经从Python服务器“断开”连接,Python只是忽略来自C#客户端的传入数据。在Python服务端断开TCP连接的合法最佳实践方式是什么?
提前感谢您。

//,非常好的问题!我对此非常感兴趣。(http://superuser.com/questions/127863/manually-closing-a-port-from-commandline/946641?noredirect=1#comment1429085_946641) 你介意展示一下你在搜索引擎上找到的“循环”解决方案中的一个或两个链接或8个单词的摘要吗? - Nathan Basanese
2个回答

2

根据官方文档:

注意:close() 释放与连接相关联的资源,但不一定立即关闭连接。如果要及时关闭连接,请在 close()之前调用 shutdown()。

因此,在调用close()之前应该调用shutdown()。另外,您还应该传递SHUT_RDWR标志以完全关闭连接:

from socket import SHUT_RDWR
...
try:
    s.shutdown(SHUT_RDWR)
    s.close()
except Exception:
    pass

“坏文件描述符”错误意味着(很可能)套接字已关闭(至少从Python端)。

2
一个错误的文件描述符通常意味着套接字已经被另一个线程关闭了。
以下是一些通用实践的想法。对于客户端,判断其是否断开连接的一种方法是检查recv()的值是否为0。如果是,则表示远程端已关闭连接。基本上,应该使用select(或poll)并将所有客户端和服务器的fd传递给select。如果在任何fd上收到读事件,则取决于fd类型,以下是发生的情况。如果fd是服务器类型,则读事件意味着有待处理的连接,您应该发出accept()来获取新连接。另一方面,如果fd是非服务器类型(即常规tcp连接),则读事件意味着有一些数据,您应该发出recv()事件以读取数据。
您需要使用循环进行选择。基本上,使用select()调用启动循环,一旦获得事件,就要对该事件执行某些操作,然后重新进入循环并发出下一个select()。您可能会发现这些链接有帮助:http://ilab.cs.byu.edu/python/select/echoserver.htmlhttp://docs.python.org/2/library/socket.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接