TCP,recv功能挂起尽管KEEPALIVE

Mic*_*rek 4 c++ sockets linux network-programming tcp

在服务器停止运行后,TCP keepalive(小超时)是否阻止客户端挂起recv?

场景:

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

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

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

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

设置KEEPALIVE选项:

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");
    }   
}
Run Code Online (Sandbox Code Playgroud)

linux 3.2.0-84-generic

小智 5

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

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