tcp 套接字上的轮询和远程关闭时没有 POLLHUP 事件

问题描述 投票:0回答:1

我想使用poll()来监听tcp套接字会话结束事件。

struct pollfd pollfd = {0};
pollfd.fd = fd;
pollfd.events = 0;

poll(&pollfd, 1, -1);

但远程关闭时没有任何事件, poll() 被阻止。如果我

poll()
POLLIN 事件,我会得到它,并且
read()
返回 0。为什么远程关闭时没有
POLLHUP
事件。

我项目中使用的代码应该是正确的,上面的代码只是一个demo。

c linux
1个回答
0
投票

根据手册页https://man7.org/linux/man-pages/man2/poll.2.html

请注意,当从管道或流套接字等通道读取数据时,此事件仅表明对等方关闭了其通道末端。

根据我的阅读,它应该给你一个

POLLHUP
,但我也没有得到它(
netstat
显示
CLOSE_WAIT
)。

在研究时我发现了这个:https://developer.illumos.narkive.com/dUe1v0Ya/poll-not-returning-pollhup-for-tcp-sockets-filled-by-the-other-end

即使你杀死-9浏览器,内核中的套接字也将被关闭,并且它将发送一个FIN,这将导致干净的关闭。即你得到 POLLIN 的长度为零的 read()。 SO_KEEPALIVE 不会参与其中。现在,如果您关闭网络接口,您最终应该会得到 POLLHUP。

看来实际的 Linux 内核实现并不遵循手册页。或者手册页的解释不同,例如“在某些情况下,您会得到 POLLHUP,但并非在所有情况下,例如干净关闭”。

© www.soinside.com 2019 - 2024. All rights reserved.