我想使用poll()来监听tcp套接字会话结束事件。
struct pollfd pollfd = {0};
pollfd.fd = fd;
pollfd.events = 0;
poll(&pollfd, 1, -1);
但远程关闭时没有任何事件, poll() 被阻止。如果我
poll()
POLLIN 事件,我会得到它,并且 read()
返回 0。为什么远程关闭时没有 POLLHUP
事件。
我项目中使用的代码应该是正确的,上面的代码只是一个demo。
根据手册页https://man7.org/linux/man-pages/man2/poll.2.html
请注意,当从管道或流套接字等通道读取数据时,此事件仅表明对等方关闭了其通道末端。
根据我的阅读,它应该给你一个
POLLHUP
,但我也没有得到它(netstat
显示CLOSE_WAIT
)。
即使你杀死-9浏览器,内核中的套接字也将被关闭,并且它将发送一个FIN,这将导致干净的关闭。即你得到 POLLIN 的长度为零的 read()。 SO_KEEPALIVE 不会参与其中。现在,如果您关闭网络接口,您最终应该会得到 POLLHUP。
看来实际的 Linux 内核实现并不遵循手册页。或者手册页的解释不同,例如“在某些情况下,您会得到 POLLHUP,但并非在所有情况下,例如干净关闭”。