TCP连接中的超时,没有数据交换

时间:2018-04-18 09:17:21

标签: c++ sockets networking tcp

我在Linux中有一个TCP客户端和服务器的C / C ++应用程序。

假设在TCP连接到位后,服务器和客户端都没有发送任何数据,而且花费了大量时间。他们甚至不发送任何心跳。

通过TCP协议,连接应该有多长时间?

连接是否由于不活动而下降?

如果有,那么我可以指定或定义任何类型的超时行为吗?

3 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

  

通过TCP协议,连接应该有多长时间?

永远。

  

连接是否由于不活动而下降?

没有

  

如果有,那么我可以指定或定义任何类型的超时行为吗?

支持SO_RCVTIMEO。这为recv()方法和朋友提供了读取超时。

答案 2 :(得分:1)

我担心唯一明智的答案应该是取决于

TCP连接可以在两端之间使用许多中间中继。每个组件(读取每一端和每个中继)可以有自己的关闭非活动连接的策略。

常见的解决方法是使用keepalive作为可选 TCP功能。它包括当连接空闲超过定义的超时时由一端发送的空数据包。对等体应该使用ACK进行应答,即使它不支持keepalive扩展,这足以维持TCP级别的连接活动。

例如,在Linux中,keepalive可以在内核级别设置,并且对所有新的TCP连接都是活动的。这可能是一个坏主意,因为默认情况下keepalive处于关闭状态以避免网络上出现问题。从引用的页面:

  

涉及keepalive的程序使用三个用户驱动的变量:

     

tcp_keepalive_time

     

发送的最后一个数据包(简单ACK不被视为数据)与第一个keepalive探测之间的间隔;在连接被标记为需要保持连接后,此计数器不再使用   tcp_keepalive_intvl

     

后续keepalive探测之间的间隔,无论在此期间连接的交换是什么

     

tcp_keepalive_probes

     

在考虑连接失效并通知应用层之前要发送的未确认探测器的数量

可以使用sysctl(8)

设置它们
 # sysctl -w \
 > net.ipv4.tcp_keepalive_time=600 \
 > net.ipv4.tcp_keepalive_intvl=60 \
 > net.ipv4.tcp_keepalive_probes=20
 net.ipv4.tcp_keepalive_time = 600
 net.ipv4.tcp_keepalive_intvl = 60
 net.ipv4.tcp_keepalive_probes = 20

也可以仅为应用程序级别的某些连接设置setsockopt

  /* Set the option active */
  int optval = 1;
  socklen_t optlen = sizeof(optval);
  if(setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
     perror("setsockopt()");
     close(s);
     exit(EXIT_FAILURE);
  }