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

timeout in a TCP connection with no exchange of data

本文关键字:数据 交换 超时 连接 TCP      更新时间:2023-10-16

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

假设在TCP连接到位后,服务器和客户端都不会在很长一段时间内发送任何数据。他们甚至不会互相发送任何心跳。

根据TCP协议,连接应该持续多长时间?

连接是否因不活动而断开?

如果是这样,是否有任何套接字选项可以在其中指定或定义任何类型的超时行为?

恐怕唯一明智的答案应该是视情况而定

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

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

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

涉及保持连接的过程使用三个用户驱动的变量:

tcp_keepalive_time

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

后续保持连接探测器之间的间隔,无论连接在此期间交换了什么

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);
}

根据TCP协议,连接应该持续多长时间?

永远。

连接是否因不活动而断开?

不。

如果是这样,是否有任何套接字选项可以在其中指定或定义任何类型的超时行为?

在支持的地方有SO_RCVTIMEO。这为recv()方法和友元提供了读取超时。

with select ?选择 - Linux 曼努埃尔页面