我正在试验Python的socketserver.TCPServer,看看它是如何工作的 .
我想我已经找到了大部分的事情,但剩下的一个问题是如何检测突然的客户端断开连接,以及它是否可能 .
到目前为止我所看到的是,如果我编写一个简单的TCPServer,并使用telnet连接它,一旦telnet断开连接,TCPServer就会知道客户端已断开连接 . 显然,它会收到一条TCP消息,告诉客户端正在断开连接 . 那很棒 .
我更进了一步,而不是关闭客户端上的telnet进程,我发送了一个SIGKILL来杀死进程,甚至没有让它清理(告诉服务器它正在断开连接) . 即使这样,服务器也知道客户端马上就离开了 . 似乎客户端的操作系统 - 而不是telnet进程 - 发送TCP FIN / RST消息告诉服务器客户端已经消失 . 也很好 .
接下来,我走了一步,当telnet客户端连接到我的TCPServer时,我告诉客户端的iptables停止与服务器通话 . 现在,绝对没有消息被发送到服务器告诉它客户端消失了 . 此时,我的TCPServer无法判断客户端是否已离开 .
我知道我可以设置一个socket.setdefaulttimeout()来阻止recv()无限期地阻塞来自客户端的消息 . 麻烦的是,如果客户端暂时保持安静(不向服务器发送任何消息),或者客户端突然消失,则会触发超时 .
所以我的问题是这样的:当一个套接字连接在服务器和客户端之间,并且客户端完全消失,而不发送TCP FIN或RST时,服务器是否有任何方式知道客户端已经消失(而不是仍然在那里,但没有发送任何消息)?或者是否有某种心跳,客户端会停止响应告诉客户端消失的主要方式?
我在某处看到TCP已经在协议中内置了keepalive,但是正常的超时是由操作系统设置的,不是可调整的,而且是几小时,不应该依赖 .
虽然我目前正在使用Python,但我认为这更像是一个通用的网络问题,而不是Python特有的 .
更新:对于任何感兴趣的人,this是我最终的结果 . 可以进行一些改进,例如添加 if __name__ == "__main__" ,处理超过1024字节的消息,但只要让客户端连接,并检测它们是否消失,它似乎工作得很好 .