《Linux高性能服务器编程》——3.9 TCP超时重传

简介: 本节书摘来自华章计算机《Linux高性能服务器编程》一书中的第3章,第3.9节,作者 游双,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.9 TCP超时重传

在3.6节~3.8节中,我们讲述了TCP在正常网络情况下的数据流。从本节开始,我们讨论异常网络状况下(开始出现超时或丢包),TCP如何控制数据传输以保证其承诺的可靠服务。

TCP服务必须能够重传超时时间内未收到确认的TCP报文段。为此,TCP模块为每个TCP报文段都维护一个重传定时器,该定时器在TCP报文段第一次被发送时启动。如果超时时间内未收到接收方的应答,TCP模块将重传TCP报文段并重置定时器。至于下次重传的超时时间如何选择,以及最多执行多少次重传,就是TCP的重传策略。我们通过实例来研究Linux下TCP的超时重传策略。

在ernest-laptop上启动iperf服务器程序,然后从Kongming20上执行telnet命令登录该服务器程序。接下来,从telnet客户端发送一些数据(此处是“1234”)给服务器,然后断开服务器的网线并再次从客户端发送一些数据给服务器(此处是“12”)。同时,用tcpdump抓取这一过程中客户端和服务器交换的TCP报文段。具体操作过程如下:

$ sudo tcpdump -n -i eth0 port 5001
$ iperf –s                    #在ernest-laptop上执行
$ telnet 192.168.1.108 5001        #在Kongming20上执行
Trying 192.168.1.108...
Connected to 192.168.1.108.
Escape character is '^]'.
1234                    #发送完之后断开服务器网线
12
Connection closed by foreign host

iperf是一个测量网络状况的工具,-s选项表示将其作为服务器运行。iperf默认监听5001端口,并丢弃该端口上接收到的所有数据,相当于一个discard服务器。上述操作过程的部分tcpdump输出如代码清单3-7所示。

image
image

TCP报文段1~3是三次握手建立连接的过程,TCP报文段4~5是客户端发送数据“1234”(应用程序数据长度为6,包括回车、换行两个字符,后同)及服务器确认的过程。TCP报文段6是客户端第一次发送数据“12”的过程。因为服务器的网线被断开,所以客户端无法收到TCP报文段6的确认报文段。此后,客户端对TCP报文段6执行了5次重传,它们是TCP报文段7~11,这可以从每个TCP报文段的序号得知。此后,数据包12~23都是ARP模块的输出内容,即Kongming20查询ernest-laptop的MAC地址。

我们保留了tcpdump输出的时间戳,以便推理TCP的超时重传策略。观察TCP报文段6~11被发送的时间间隔,它们分别为0.2?s、0.4?s、0.8?s、1.6?s和3.2?s。由此可见,TCP一共执行5次重传,每次重传超时时间都增加一倍(因此,和TCP超时重连的策略相似)。在5次重传均失败的情况下,底层的IP和ARP开始接管,直到telnet客户端放弃连接为止。

Linux有两个重要的内核参数与TCP超时重传相关:/proc/sys/net/ipv4/tcp_retries1和/proc/sys/net/ipv4/tcp_retries2。前者指定在底层IP接管之前TCP最少执行的重传次数,默认值是3。后者指定连接放弃前TCP最多可以执行的重传次数,默认值是15(一般对应13~30?min)。在我们的实例中,TCP超时重传发生了5次,连接坚持的时间是15?min(可以用date命令来测量)。

虽然超时会导致TCP报文段重传,但TCP报文段的重传可以发生在超时之前,即快速重传,这将在下一节中讨论。

相关文章
|
2月前
|
Shell Linux
Linux shell编程学习笔记30:打造彩色的选项菜单
Linux shell编程学习笔记30:打造彩色的选项菜单
|
25天前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
1月前
|
网络协议 Java API
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
62 2
|
1月前
|
存储 网络协议 Java
【网络】UDP和TCP之间的差别和回显服务器
【网络】UDP和TCP之间的差别和回显服务器
65 1
|
2月前
|
Shell Linux
Linux shell编程学习笔记82:w命令——一览无余
Linux shell编程学习笔记82:w命令——一览无余
|
2月前
|
Linux Shell
Linux系统编程:掌握popen函数的使用
记得在使用完 `popen`打开的流后,总是使用 `pclose`来正确关闭它,并回收资源。这种做法符合良好的编程习惯,有助于保持程序的健壮性和稳定性。
106 6
|
1月前
|
网络协议 Python
Python创建一个TCP服务器
Python创建一个TCP服务器
|
2月前
|
Linux Shell
Linux系统编程:掌握popen函数的使用
记得在使用完 `popen`打开的流后,总是使用 `pclose`来正确关闭它,并回收资源。这种做法符合良好的编程习惯,有助于保持程序的健壮性和稳定性。
144 3
|
2月前
|
Shell Linux Python
python执行linux系统命令的几种方法(python3经典编程案例)
文章介绍了多种使用Python执行Linux系统命令的方法,包括使用os模块的不同函数以及subprocess模块来调用shell命令并处理其输出。
39 0
|
3月前
|
项目管理 敏捷开发 开发框架
敏捷与瀑布的对决:解析Xamarin项目管理中如何运用敏捷方法提升开发效率并应对市场变化
【8月更文挑战第31天】在数字化时代,项目管理对软件开发至关重要,尤其是在跨平台框架 Xamarin 中。本文《Xamarin 项目管理:敏捷方法的应用》通过对比传统瀑布方法与敏捷方法,揭示敏捷在 Xamarin 项目中的优势。瀑布方法按线性顺序推进,适用于需求固定的小型项目;而敏捷方法如 Scrum 则强调迭代和增量开发,更适合需求多变、竞争激烈的环境。通过详细分析两种方法在 Xamarin 项目中的实际应用,本文展示了敏捷方法如何提高灵活性、适应性和开发效率,使其成为 Xamarin 项目成功的利器。
53 1
下一篇
无影云桌面