我在Linux中有一个TCP客户端和服务器的C / C ++应用程序。
假设在TCP连接到位后,服务器和客户端都没有发送任何数据,而且花费了大量时间。他们甚至不发送任何心跳。
通过TCP协议,连接应该有多长时间?
连接是否由于不活动而下降?
如果有,那么我可以指定或定义任何类型的超时行为吗?
答案 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); }