das*_*sen 9 c sockets networking
在客户端,我有一个
close(sockfd)
Run Code Online (Sandbox Code Playgroud)
其中sockfd是连接到服务器的套接字.在服务器中我得到了这个:
if (sockfd.revents & POLLERR ||
desc_set[i].revents & POLLHUP || desc_set[i].revents & POLLNVAL) {
close(sockfd.fd);
printf("Goodbye (connection closed)\n");
}
Run Code Online (Sandbox Code Playgroud)
其中sockfd是struct pollfd,而sockfd.fd是客户端套接字的文件描述符.
当客户端像我放在那里那样关闭套接字时,服务器似乎没有用第二个代码(desc_set [i] .revents&POLLHUP等)检测它.
有谁知道这是什么问题?
Fle*_*exo 11
听起来你已经成功地从客户端关闭了一半的连接.在这种状态下,连接仍然可以在一个方向上发送数据,即它以半双工模式运行.这是设计使并且允许您的服务器完成对客户端发送的任何内容的回复.通常,这意味着完成文件传输和调用close(),或回答查询的所有方面.在半关闭状态下,您仍然可以非常明智地将数据发送到已经调用的一侧close().在您的服务器中,如果您尝试阅读,您将看到eof.close()只是意味着"我已经完成了发送,完成了我要求的任何事情".
POLLHUP,POLLERR并且POLLNVAL只检查本地连接的输出端,这在此处仍然有效.有一个POLLRDHUP,这是一个GNU扩展,应该检测另一边关闭,但你正在做的测试只是检查它是否仍然可写,而不是它仍然可读.
另见这个问题,这是谈论java,但仍然非常相关.
远程关闭或输出关闭既不是错误,挂断也不是无效状态。这是一个读取事件,因此read()将返回零。只需将其作为常规读取处理的一部分进行处理即可。
顺便说一句,您上面的测试条件应为sockfd.revents&(POLLERR | POLLHUP | POLLNVAL)。