c - 检测客户端应用程序何时按顺序关闭连接

标签 c sockets server client-server

我正在开发一个 9p 服务器,它非常像一个 nfs 服务器。随后的安装和卸载不会导致套接字描述 rune 件泄漏,因为我能够关闭套接字。但是,在以下情况下,服务器不会进行适当的清理并关闭套接字。场景是,当机器 A 的客户端从服务器机器挂载 FS 时。然后由于某种原因,机器 A 重新启动或关闭。如果发生这种情况,我希望服务器清理工作并关闭套接字,但由于某种原因它会阻塞 read()。我认为当连接关闭时 read() 应该返回 0,但事实并非如此。我认为这是因为没有发生正确的 tcp 终止,因此服务器正在等待来自客户端的一些数据。这是我的服务器的伪代码

while(1){

    n = read(sockfd, buffer, 4); //4 is protocol header that specifies the size
    if ( n == 0 ) break;
    /* iteratively read the rest of bytes until the incoming message ends */
}
cleanup(); // close socket and some other tasks

但是,当客户端重新启动而服务器阻塞读取时,什么也不会发生。解决这个问题的最佳方法和最简单的方法是什么?有些人建议运行一个单独的线程来检查连接,但这太复杂了。我确信一定有更快的方法

最佳答案

当客户端关闭时,客户端上的操作系统将终止所有 TCP 连接。但是,当客户端崩溃或关闭时,或者当客户端和服务器之间的路径某处发生网络问题时,则无法将信息传递到服务器,并且服务器可能会被阻止在 read() 中。永远打电话。

有两种可能的解决方案。您可以使用标准 TCP 保持事件探测,也可以实现应用程序级别的运行状况检查。

TCP 保持事件状态

TCP 保持事件状态在 http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html 中有很好的描述。 :

In order to understand what TCP keepalive (which we will just call keepalive) does, you need do nothing more than read the name: keep TCP alive. This means that you will be able to check your connected socket (also known as TCP sockets), and determine whether the connection is still up and running or if it has broken...

当您希望应用程序使用 TCP 保持事件状态时,只需设置套接字选项(缺少错误检查):

int optval = 1;
socklen_t optlen = sizeof(optval);
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);

TCP 保持事件状态很容易使用,但它取决于操作系统配置,并且应用程序无法设置自己的超时,因为它们是在系统范围内可配置的。

应用程序级别健康检查

当您需要应用程序特定的超时来检测断开连接时,请使用应用程序级机制。有很多方法可以实现它。这个想法是定期发送一段无用的数据,并假设连接在未收到时被破坏。

关于c - 检测客户端应用程序何时按顺序关闭连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32661542/

相关文章:

c - K&R 如何重置字符数组?

c - 用一种类型替换另一种类型

c++ - 如何在 Windows 中将套接字设置为阻塞模式?

perl - 多个系统读取导致以下系统写入在 Perl 中失败

php - 我究竟在哪里可以检查错误日志以了解 500 错误?

java - 炸弹人网络通讯-无法发送炸弹

node.js - 为什么我的 Node.js 服务器进程被克隆?

c - WC 没有执行任何操作

c - 我的 print_random_sprites 函数有什么问题?

eclipse + tomcat错误