TCP 连接超时以及测试用例
1、问题:
工作中遇到一个问题:在建立一个 TCP 连接时,如果因为超时而无法建立,那么这个超时时间时多少?
2、理论计算:
这个值可以通过计算得到:
在 Linux 内核源码中, linux-2.6.18/include/net/tcp.h 中,定义了如下宏
#define TCP_SYN_RETRIES 5 /* number of times to retry active opening a
* connection: ~180sec is RFC minimum */
#define TCP_RTO_MAX ((unsigned)(120*HZ))
TCP_SYN_RETRIES 规定了在主动发起一个 TCP 连接时,重传的次数
TCP_RTO_MAX 规定了 RTO 的最大值
Linux 把 RTO 的初始值设置为 3s (where?),同时我们知道在重传的情况下,用 Karn 算法倍增 RTO 值,因此超时时间是:
3 + 6 + 12 + 24 + 48 + 96 == 189 seconds
3、测试用例
问题是需要设计一个测试用例来验证这个结果。开始以为这个问题很简单,结果尝试了几种办法都没有成功,最后采用的测试步骤如下:
1、假设测试用 Linux 机器的 IP 地址是 192.168.0.1;不用连接任何网络2、在系统的 ARP cache 中增加一个到 192.168.0.2 的映射,映射后的 MAC 地址可以为一个任意值,例如我这里用的是 00:00:00:00:00:11
# ip neigh add 192.168.0.2 lladdr 00:00:00:00:00:11 dev eth0
3、写一个简单的测试程序 tcpconn,可以连接指定的 IP 和端口
4、用 time 这个工具执行 tcpconn ,去连接 192.168.0.2 的一个任意端口,例如 1000
# time ./tcpconn 192.168.0.2 1000
5、最后从 time 的输出结果,可以验证上面的理论计算值
6、在跑这个测试的时候,最好另开一个窗口,用 tcpdump 观察过程;如果不愿意写 tcpconn,也可以用 telnet 这个工具,但是测试结果会有一些偏差。
这个测试用例的关键在于在 ARP cache 中添加一个映射,以绕过 Linux 的 neighbour discovery 机制。通过这个测试用例,可以更好的理解 TCP/IP 协议。