《Linux高性能服务器编程》——3.3 TCP连接的建立和关闭-阿里云开发者社区

开发者社区> 华章计算机> 正文

《Linux高性能服务器编程》——3.3 TCP连接的建立和关闭

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

3.3 TCP连接的建立和关闭

本节我们讨论建立和关闭TCP连接的过程。

3.3.1 使用tcpdump观察TCP连接的建立和关闭

首先从ernest-laptop上执行telnet命令登录Kongming20的80端口,然后抓取这一过程中客户端和服务器交换的TCP报文段。具体操作过程如下:

$ sudo tcpdump -i eth0 –nt '(src 192.168.1.109 and dst 192.168.1.108) or (src 192.168.1.108 and dst 192.168.1.109)' 
$ telnet 192.168.1.109 80
Trying 192.168.1.109...
Connected to 192.168.1.109.
Escape character is '^]'.
^](回车)  # 输入ctrl+]并回车

telnet> quit(回车)
Connection closed.

当执行telnet命令并在两台通信主机之间建立TCP连接后(telnet输出“Connected to 192.168.1.109”),输入Ctrl+]以调出telnet程序的命令提示符,然后在telnet命令提示符后输入quit以退出telnet客户端程序,从而结束TCP连接。整个过程中(从连接建立到结束),tcpdump输出的内容如代码清单3-2所示。

image

因为整个过程并没有发生应用层数据的交换,所以TCP报文段的数据部分的长度(length)总是0。为了更清楚地表示建立和关闭TCP连接的整个过程,我们将tcpdump输出的内容绘制成图3-6所示的时序图。

image

第1个TCP报文段包含SYN标志,因此它是一个同步报文段,即ernest-laptop(客户端)向Kongming20(服务器)发起连接请求。同时,该同步报文段包含一个ISN值为535734930的序号。第2个TCP报文段也是同步报文段,表示Kongming20同意与ernest-laptop建立连接。同时它发送自己的ISN值为2159701207的序号,并对第1个同步报文段进行确认。确认值是535734931,即第1个同步报文段的序号值加1。前文说过,序号值是用来标识TCP数据流中的每一字节的。但同步报文段比较特殊,即使它并没有携带任何应用程序数据,它也要占用一个序号值。第3个TCP报文段是ernest-laptop对第2个同步报文段的确认。至此,TCP连接就建立起来了。建立TCP连接的这3个步骤被称为TCP三次握手。

从第3个TCP报文段开始,tcpdump输出的序号值和确认值都是相对初始ISN值的偏移。当然,我们可以开启tcpdump的-S选项来选择打印序号的绝对值。

后面4个TCP报文段是关闭连接的过程。第4个TCP报文段包含FIN标志,因此它是一个结束报文段,即ernest-laptop要求关闭连接。结束报文段和同步报文段一样,也要占用一个序号值。Kongming20用TCP报文段5来确认该结束报文段。紧接着Kongming20发送自己的结束报文段6,ernest-laptop则用TCP报文段7给予确认。实际上,仅用于确认目的的确认报文段5是可以省略的,因为结束报文段6也携带了该确认信息。确认报文段5是否出现在连接断开的过程中,取决于TCP的延迟确认特性。延迟确认将在后面讨论。

在连接的关闭过程中,因为ernest-laptop先发送结束报文段(telnet客户端程序主动退出),故称ernest-laptop执行主动关闭,而称Kongming20执行被动关闭。

一般而言,TCP连接是由客户端发起,并通过三次握手建立(特殊情况是所谓同时打开[1])的。TCP连接的关闭过程相对复杂一些。可能是客户端执行主动关闭,比如前面的例子;也可能是服务器执行主动关闭,比如服务器程序被中断而强制关闭连接;还可能是同时关闭(和同时打开一样,非常少见)。

3.3.2 半关闭状态

TCP连接是全双工的,所以它允许两个方向的数据传输被独立关闭。换言之,通信的一端可以发送结束报文段给对方,告诉它本端已经完成了数据的发送,但允许继续接收来自对方的数据,直到对方也发送结束报文段以关闭连接。TCP连接的这种状态称为半关闭(half close)状态,如图3-7所示。

image

请注意,在图3-7中,服务器和客户端应用程序判断对方是否已经关闭连接的方法是:read系统调用返回0(收到结束报文段)。当然,Linux还提供其他检测连接是否被对方关闭的方法,这将在后续章节讨论。

socket网络编程接口通过shutdown函数提供了对半关闭的支持,我们将在后续章节讨论它。这里强调一下,虽然我们介绍了半关闭状态,但是使用半关闭的应用程序很少见。

3.3.3 连接超时

前面我们讨论的是很快建立连接的情况。如果客户端访问一个距离它很远的服务器,或者由于网络繁忙,导致服务器对于客户端发送出的同步报文段没有应答,此时客户端程序将产生什么样的行为呢?显然,对于提供可靠服务的TCP来说,它必然是先进行重连(可能执行多次),如果重连仍然无效,则通知应用程序连接超时。

为了观察连接超时,我们模拟一个繁忙的服务器环境,在ernest-laptop上执行下面的操作:

$ sudo iptables -F
$ sudo iptables -I INPUT -p tcp --syn -i eth0 -j DROP

iptable命令用于过滤数据包,这里我们利用它来丢弃所有接收到的连接请求(丢弃所有同步报文段,这样客户端就无法得到任何确认报文段)。

接下来从Kongming20上执行telnet命令登录到ernest-laptop,并用tcpdump抓取这个过程中双方交换的TCP报文段。具体操作如下:

$ sudo tcpdump -n -i eth0 port 23    #仅抓取telnet客户端和服务器交换的数据包
$ date; telnet 192.168.1.108; date    #在telnet命令前后都执行date命令,以计算超时时间
Mon Jun 11 21:23:35 CST 2012
Trying 192.168.1.108...
telnet: connect to address 192.168.1.108: Connection timed out
Mon Jun 11 21:24:38 CST 2012

从两次date命令的输出来看,Kongming20建立TCP连接的超时时间是63?s。本次tcpdump的输出如代码清单3-3所示。

image

这次抓包我们保留了tcpdump输出的时间戳(不使用其-t选项),以便推理Linux的超时重连策略。

我们一共抓取到6个TCP报文段,它们都是同步报文段,并且具有相同的序号值,这说明后面5个同步报文段都是超时重连报文段。观察这些TCP报文段被发送的时间间隔,它们分别为1?s、2?s、4?s、8?s和16?s(由于定时器精度的问题,这些时间间隔都有一定偏差),可以推断最后一个TCP报文段的超时时间是32?s(63?s-16?s-8?s-4?s-2?s-1?s)。因此,TCP模块一共执行了5次重连操作,这是由/proc/sys/net/ipv4/tcp_syn_retries内核变量所定义的。每次重连的超时时间都增加一倍。在5次重连均失败的情况下,TCP模块放弃连接并通知应用程序。

在应用程序中,我们可以修改连接超时时间,具体方法将在本书后续章节中进行介绍。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《高性能Linux服务器构建实战》——1.4节Nginx的安装与配置
本节书摘来自华章社区《高性能Linux服务器构建实战》一书中的第1章,第1.4节Nginx的安装与配置,作者:高俊峰,更多章节内容可以访问云栖社区“华章社区”公众号查看
1481 0
开启irqbalance提升服务器性能
操作系统 性能调休   公司有次压测存在一个问题:CPU资源压不上去,一直在40%已达到了性能瓶颈,后定位到原因,所在的服务器在压测过程中产生的中断都落在CPU0上处理,这种中断并没有均衡到各个CPU,导致单个CPU过载而形成瓶颈。
5583 0
《多核与GPU编程:工具、方法及实践》----1.4 性能指标
发展多核硬件和开发多核软件的目标是获取更高性能,例如更短的执行时间、更大规模的问题和更大的数据集等。很明显,这需要一个客观的标准或者准则来评估这些努力的有效性。
2635 0
Java性能优化之编程技巧总结
1、慎用异常 在Java软件开发中,经常使用 try-catch 进行错误捕获,但是,try-catch 语句对系统性能而言是非常糟糕的。
833 0
服务器性能测试典型工具介绍
http://server.51cto.com/Eva-30167.htm
508 0
就是要你懂 TCP-- 最经典的TCP性能问题
# 就是要你懂 TCP-- 最经典的TCP性能问题 ### 问题描述 某个PHP服务通过Nginx将后面的tair封装了一下,让其他应用可以通过http协议访问Nginx来get、set 操作tair 上线后测试一切正常,每次操作几毫秒,但是有一次有个应用的value是300K,这个时候set一次需要300毫秒以上。 在没有任何并发压力单线程单次操作也需要这么久,这个延迟是没有道
3286 0
Linux上节点服务器启动正常,计算机连接不上
         最近在Linux上的Weblogic上创建自己的Machine时,发现监控的nodeManager的状态一直是异常的。经查找资料发现,在启动nodeManager时使用到的配置中默认是启用了安全访问协议的,即SecureListener=true。
657 0
10059
文章
0
问答
来源圈子
更多
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载