基于select的TCP服务器如何感知客户端已断开连接?
核心原理:这是TCP协议本身的内置机制,不需要你在应用层写代码发送断开通知
具体实现逻辑分三层:
- 第一层:TCP连接的关闭是内核协议栈自动处理的
当你在客户端输入QUIT触发done = True之后,客户端主线程会跳出循环,最后执行s_tcp.close()关闭和服务端的TCP连接。此时客户端操作系统的TCP/IP栈会自动向服务端发送FIN握手包,完成四次挥手的断开流程,这个过程完全由操作系统内核处理,不需要应用层写任何发送逻辑。 - 第二层:select会把断开的TCP连接标记为可读
服务端把所有已接入的客户端TCP socket都加入了select.select()的可读监听队列,当服务端内核收到客户端发来的FIN包后,会把对应的客户端socket标记为可读状态,触发select返回。 - 第三层:你的服务端逻辑刚好适配了当前场景的特性
你的业务逻辑里,客户端从来不会主动向服务端发送任何应用层数据,所以客户端socket触发可读的唯一可能性就是连接断开。因此你服务端代码里只要非监听socket触发可读,就直接执行断开清理逻辑,刚好能正常运行。
注意:你的服务端代码存在不严谨的问题,如果后续客户端需要给服务端发送应用层消息,现有逻辑会把正常的消息传输误判为连接断开。标准写法应该是在else分支先调用
recv读取数据,如果返回空字节(b'')再判定为连接断开,否则按正常业务消息处理。
内容的提问来源于stack exchange,提问作者sad-panda
相关产品推荐
相关产品推荐

