为什么我写的这个服务器没有检测到客户端已经关闭了它的套接字?

发布于 2024-10-02 07:18:32 字数 485 浏览 5 评论 0原文

在客户端中,我有一个

close(sockfd)

sockfd ,其中 sockfd 是连接到服务器的套接字。 在服务器中,我得到了这个:

if (sockfd.revents & POLLERR ||
    desc_set[i].revents & POLLHUP || desc_set[i].revents & POLLNVAL) { 
  close(sockfd.fd); 
  printf("Goodbye (connection closed)\n");
}

其中 sockfd 是一个 struct pollfd,而 sockfd.fd 是客户端套接字的文件描述符。

当客户端像我在那里那样关闭套接字时,服务器似乎没有使用第二个代码(desc_set[i].revents & POLLHUP 等)检测到它。

有谁知道有什么问题吗?

In the client, I have a

close(sockfd)

where sockfd is the socket that's connected to the server.
In the server I've got this:

if (sockfd.revents & POLLERR ||
    desc_set[i].revents & POLLHUP || desc_set[i].revents & POLLNVAL) { 
  close(sockfd.fd); 
  printf("Goodbye (connection closed)\n");
}

Where sockfd is a struct pollfd, and sockfd.fd is the file descriptor of the client's socket.

When the client closes the socket like I put up there, the server doesn't seem to detect it with the second code (desc_set[i].revents & POLLHUP, etc.).

Does anyone know what's the problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

随心而道 2024-10-09 07:18:32

听起来您已经成功地从客户端半关闭连接。在这种状态下,连接仍然可以在一个方向上发送数据,即它以半双工模式运行。这是设计使然,将允许您的服务器完成对客户端发送的任何内容的回复。通常,这意味着完成文件传输并调用 close(),或回答查询的所有方面。 在半关闭状态下,您仍然可以相当明智地向已调用 close() 的一侧发送数据。如果您尝试阅读,在您的服务器中您将看到 eof。 close() 只是意味着“我已完成发送,完成我要求的任何内容”。

POLLHUPPOLLERRPOLLNVAL 只检查本地连接的输出端,在这里仍然有效。有一个 POLLRDHUP,它是一个 GNU 扩展,应该检测另一端关闭,但您所做的测试只是检查它是否仍然可写,而不是检查它是否仍然可读。

另请参阅此问题,这是在谈论java,但仍然非常相关。

Sounds like you've managed to half close the connection from the client side. In this state the connection can still send data in one direction, i.e. it operates in half-duplex mode. This is by design and would allow your server to finish replying to whatever the client sent. Typically this would mean completing a file transfer and calling close(), or answering all of the aspects of the query. In the half-closed state you can still quite sensibly send data to the side that has already called close(). In your server you will see eof if you try to read though. close() just means "I'm done sending, finish up whatever I asked for".

POLLHUP, POLLERR and POLLNVAL only checks the output side of the local connection, which is still valid here. There's a POLLRDHUP, which is a GNU extension that should detect the other side closing, but the tests you're doing are only checking if it's still writable, not if it's still readable.

See also this question, which is talking about java, but still very related.

梦魇绽荼蘼 2024-10-09 07:18:32

远程关闭或输出关闭既不是错误,也不是挂起,也不是无效状态。这是一个读取事件,read() 将返回零。只需将其作为正常读取处理的一部分来处理即可。

顺便说一句,您上面的测试条件应阅读 sockfd.revents & (POLLERR|POLLHUP|POLLNVAL)。

A remote close or output shutdown is neither an error nor a hangup nor an invalid state. It is a read event such that read() will return zero. Just handle it as part of your normal read processing.

BTW your test condition above should read sockfd.revents & (POLLERR|POLLHUP|POLLNVAL).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文