开发者

socket: constantly getting POLLHUP on half-close

I wrote a socket server, running on linux, but this is probably not linux specifix.

I use poll() to check the state of the clients. My clients do an active (half-)close after sending the request. The server constantly getting POLLHUP and POLLERR, because of the client's half-cl开发者_开发技巧ose. I also see POLLRDHUP, so I know that's actually half-close and not a connection close/reset. My problem is that I always get these events even though I already know from previous poll that there was a half-close.

How can I disable this so I do not receive theis event anymore? I tried to do additional read() and do a shutdown(fd, SHUT_RD), but it doesn't seem to help. I don't want poll to wake up for an event I already handled.


Stop including the fd in the readfds set once you get the half close. There's nothing left to read except half-closes. From this point the only thing you can be interested in is 'writable' events.


Just ignore POLLHUP in return flags. The existing code, if correct, will then do what you want.

The fact that you will keep getting half-closes from poll() (outlined by EJP's answer) is a feature, not a bug. It lets you treat half-closed exactly like end-of-file; which is exactly what you want, as in, it lets your application read the last bytes in the socket buffer instead of discarding them (which is the correct semantics of TCP half-close).

Once "ordinary" end-of-file is reached, poll() will always select the file descriptor as ready for read. The loop around poll() is then supposed to read() the data until end-of-file is seen, and then close(). Ignoring the POLLHUP condition lets your program do the exact same thing with the same code in half-closed situations, and get at the last bytes in the socket buffer.

Likewise, you should implement control flow without caring about POLLHUP. If (and only if) you need to throttle a file descriptor (i.e. there is currently nowhere to put the read() bytes into), then remove that descriptor from the poll() set, so that the kernel won't bug you with ready-to-read "interrupts" until you tell it to again (unthrottling). The fact that all the data is already in the socket buffer (which is what the POLLHUP bit indicates) again doesn't make a difference.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜