本文介绍了尽管 KEEPALIVE,TCP,recv 功能仍挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在服务器死机后,TCP keepalive(带有小超时)是否会阻止客户端挂在 recv 上?

Is TCP keepalive (with small timeouts) preventing client from hanging on recv, after the server is dead?

场景:

服务器和客户端运行在不同的机器上:

Server and client running on separate machines:

  1. 客户端通过带有 KEEPALIVE 选项的 TCP 连接到服务器
  2. 客户端发送Hello server"并等待响应
  3. 服务器收到Hello server"并响应Hello client"
  4. 客户端收到响应,休眠 10 秒并重复第 2-4 步(现在跳过第 1 步 - 保留连接)

在客户端休眠期间,服务器被关闭,现在:

During the client sleep, the server is plugged off, now:

  1. 客户端醒来
  2. 发送Hello server"并等待响应
  3. 20 分钟后 recv 放弃 - 我原以为 KEEPALIVE 会在 45 秒后打破 recv 功能:

设置 KEEPALIVE 选项:

Setting KEEPALIVE options:

void TCPclient::setkeepalive()
{
   int optval;
   socklen_t optlen = sizeof(optval);

   /* Check the status for the keepalive option */
   if(getsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
        throw std::string("getsockopt");
   }

   optval = 1;
   optlen = sizeof(optval);
   if(setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
      close(s);
      exit(EXIT_FAILURE);
   }

    optval = 2;
    if (setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &optval, optlen) < 0) {
        throw std::string("setsockopt");
    }

    optval = 15;
    if (setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &optval, optlen) < 0) {
        throw std::string("setsockopt");
    }

    optval = 15;
    if (setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &optval, optlen) < 0) {
        throw std::string("setsockopt");
    }
}

linux 3.2.0-84-generic

推荐答案

当线路空闲 15 秒后,Keepalive 变为活动状态.在您的情况下,Keepalive 启动超时为 15 秒,睡眠为 10 秒,这意味着Hello server"将是服务器被杀死后要发送的下一个命令.

Keepalive becomes active when the line has been idle for 15 secs. In your case Keepalive kick off timeout is 15 secs, the sleep is 10 secs, which means "Hello server" will be the next command to be sent after the server is killed.

您的 Linux 将尝试多次重新传输该消息.Keepalive 仍然不会被触发.达到重试限制后连接将中断 - 这将需要 10-30 分钟.

Your Linux will try to retransmit the message several times. Keepalive still won't be triggered. The connection will break after the limit of retries is reached - that will take 10-30 minutes.

这篇关于尽管 KEEPALIVE,TCP,recv 功能仍挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 05:13