socket:不断关闭POLLHUP

时间:2011-07-07 11:33:28

标签: sockets unix networking half-close

我写了一个在linux上运行的套接字服务器,但这可能不是linux规范。

我使用poll()来检查客户端的状态。发送请求后,我的客户端处于活动状态(半)关闭状态。由于客户端的半关闭,服务器不断获得POLLHUPPOLLERR。我也看到POLLRDHUP,所以我知道它实际上是半关闭而不是连接关闭/重置。我的问题是,我总是得到这些事件,即使我从之前的民意调查中已经知道有一半关闭。

如何禁用此功能,以便我不再收到该事件?我尝试执行其他read()并执行shutdown(fd, SHUT_RD),但似乎没有帮助。我不希望poll为我已经处理过的事件醒来。

2 个答案:

答案 0 :(得分:3)

一旦你关闭一半,就停止在readfds集中包含fd。除了半关闭之外,没有什么可以读了。从这一点来说,你唯一感兴趣的是'可写'事件。

答案 1 :(得分:0)

在回复标记中忽略POLLHUP。现有的代码,如果正确的话,那就可以做你想要的了。

你将继续从poll()(由EJP的回答概述)半关闭的事实是一个功能,而不是一个错误。它可以让你完全像文件末尾一样处理半封闭;这正是你想要的,因为它让你的应用程序读取套接字缓冲区中的最后一个字节而不是丢弃它们(这是TCP半关闭的正确语义)。

一旦达到“普通”文件结束,poll()将始终选择文件描述符作为准备读取。然后,poll()周围的循环应该read()数据,直到看到文件结尾,然后是close()。忽略POLLHUP条件允许程序在半闭的情况下使用相同的代码执行完全相同的操作,并获取套接字缓冲区中的最后一个字节。

同样,您应该在不关心POLLHUP的情况下实施控制流程。如果(并且仅当)您需要限制文件描述符(即,当前无处放置read()个字节),则从poll()集中删除该描述符,这样内核就不会用准备好的“中断”来阻止你,直到你再次告诉它(非节流)。所有数据已经​​在套接字缓冲区中(这是POLLHUP位指示的内容)的事实再次没有区别。