TCP套接字远程关闭时调用poll()未触发POLLHUP事件的原因
关于poll()监控TCP套接字会话结束事件的疑问解答
你提供的示例代码中,pollfd.events被设为0:
struct pollfd pollfd = {0}; pollfd.fd = fd; pollfd.events = 0; poll(&pollfd, 1, -1);
出现远程关闭时poll()阻塞不返回,以及监听POLLIN才触发事件的原因,可从两方面解释:
- poll()的events字段作用:这个字段是你明确告诉内核需要监控的事件集合。设为0等于让内核不监控任何事件,不管连接发生POLLIN、POLLHUP还是其他变化,poll()都会持续阻塞,因为你没要求它检测这些事件。
- TCP连接关闭的事件触发逻辑:
当远程主动发送FIN包关闭连接时,本地套接字的读缓冲区会被标记为“存在EOF可读”,此时内核触发POLLIN事件——因为调用read()会返回0(代表读到文件末尾)。这种场景下,本地套接字的写端仍然可用(除非本地主动关闭写端),而POLLHUP事件的触发条件是连接的写方向完全不可用(比如远程发送RST重置连接,或连接双方都完成关闭操作),所以此时不会触发POLLHUP。
如果需要同时覆盖“EOF可读”和“连接挂起”两种关闭场景,可将events设为POLLIN | POLLHUP,这样两种情况发生时poll()都会返回。
内容的提问来源于stack exchange,提问作者yuanjianpeng
相关产品推荐
相关产品推荐

