我有一个 python tcp 服务器,每个连接都有一个线程来监听。当我调用close
连接对象异常时,会抛出“错误的文件描述符”。通过谷歌搜索,我找到了一些解决方案,每个解决方案都使用循环来接收客户端数据并在他们决定断开客户端连接时打破该循环。我的客户端是用 C# 编写的并且没有“获取”,它与服务器“断开连接”,python 只是忽略来自 C# 客户端的传入数据。在 python 中从服务器端断开 tcp 连接的合法最佳实践方法是什么?
提前致谢
我有一个 python tcp 服务器,每个连接都有一个线程来监听。当我调用close
连接对象异常时,会抛出“错误的文件描述符”。通过谷歌搜索,我找到了一些解决方案,每个解决方案都使用循环来接收客户端数据并在他们决定断开客户端连接时打破该循环。我的客户端是用 C# 编写的并且没有“获取”,它与服务器“断开连接”,python 只是忽略来自 C# 客户端的传入数据。在 python 中从服务器端断开 tcp 连接的合法最佳实践方法是什么?
提前致谢
错误的文件描述符很可能意味着套接字已被另一个线程关闭。
以下是对一般实践的一些想法。对于客户端,知道它是否断开连接的一种方法是检查 recv() 值是否为 0。如果是,则表示远程端已关闭连接。基本上,您应该使用 select(或 poll)并传递所有客户端和服务器的 fds 来选择。如果您在任何 fd 上收到读取事件,则根据 fd 类型,会发生以下情况。如果 fd 是服务器类型,那么 read 事件意味着有一个挂起的连接,你应该发出一个 accept() 来获取新的连接。另一方面,如果 hte fd 是非服务器类型(意味着常规的 tcp 连接),则读取事件意味着有一些数据,您应该发出 recv() 事件来读取数据。
您将使用循环进行选择。基本上,使用 select() 调用开始循环,一旦你得到一个事件,对那个事件做一些事情,然后重新进入循环并发出下一个 select()。您可能会发现这些链接很有帮助:http: //ilab.cs.byu.edu/python/select/echoserver.html和http://docs.python.org/2/library/socket.html
从文档:
注意:close() 释放与连接关联的资源,但不一定立即关闭连接。如果要及时关闭连接,请在 close() 之前调用 shutdown()。
所以你应该在打电话shutdown()
之前打电话close()
。此外,您应该传递SHUT_RDWR
标志以完全关闭连接:
from socket import SHUT_RDWR
...
try:
s.shutdown(SHUT_RDWR)
s.close()
except Exception:
pass
“错误的文件描述”错误意味着(很可能)套接字已经关闭(至少从 Python 端)。