网络编程-超时连接(上)

Posted by 周思进 on December 4, 2019

问题场景:
linux客户端和服务器进行TCP连接,配置错误的TCP服务器和端口,等待连接操作返回需要2分钟左右,这个时间就有点久了,考虑服务器正常运行的情况建立连接花不了几秒,比如顶多等待15秒,如果连接还没成功,就认为和服务器连接失败,直接返回,而不用等待2分钟后再返回。

实际测试过程中发现有如下几种情况(Ubuntu系统):
(说明:只测试连接,所以可以直接使用telnet ip port方式测试连接效果,如果需要计算从连接到执行的大概时间,可以通过如下方式:date; telnet ip port; date)

1、如果是同一局域网明确存在的主机地址,但该主机地址不存在所要访问的服务监听端口,客户端直接收到RST报文结束。

RST

2、如果是同一局域网,但不存在目标主机,抓包显示很快发送完6个ARP查询,无结果返回No route to host。

ARP查询

arp尝试发送间隔时间这个搜索无果…

3、对于是非同一局域网的目标主机访问,无论是目标主机不存在,还是目标主机存在,但端口不存在,其返回结果都是一样的,都是第一次失败后再尝试连续发送6次SYN包无果后超时返回

重传


上面重传SYN包的次数由如下配置决定
#cat /proc/sys/net/ipv4/tcp_syn_retries
6

该字段的内核文档说明如下

Number of times initial SYNs for an active TCP connection attempt will be retransmitted. Should not be higher than 127. Default value is 6, which corresponds to 63seconds till the last retransmission with the current initial RTO of 1second. With this the final timeout for an active TCP connection attempt will happen after 127seconds.

这里的说明中最后一个重传包在63秒,跟上面抓包显示一致,而后说最后超时在127秒发生,也就是connect接口实际返回时已经过去了的超时时间,说明在最后63秒发送了最后一次syn包之后,系统在等待了64秒(从图中看TCP握手SYN包超时重试按照2的幂来计算的)之后无收到响应包才返回。

如果将该配置修改成2次进行测试
#echo 2 > /proc/sys/net/ipv4/tcp_syn_retries

修改之后抓包显示,就只有2次重传了

2次重传

虽然这样修改重传次数少了,间接等待的时间少了,不过在正常工作环境一般不会随意修改这个值。