TCP 连接的建立和终止

三路握手

建立一个TCP连接时会发生下述情形。

(1)服务器必须准备好接受外来的连接。这通常通过调用socket、bind和listen这3个函数来完成的,我们称之为被动打开。

(2)客户通过调用connect发起主动打开。这导致客户TCP发送一个SYN(同步)分节,它告诉服务器客户将在(待建立的)连接中发送的数据的初始序列号。通常SYN分节不携带数据,其所在IP数据报只含有一个IP首部、一个TCP首部及可能有的TCP选项。

(3)服务器必须确认(ACK)客户的SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器在单个分节中发送SYN和对客户SYN的ACK(确认)。

(4)客户必须确认服务器的SYN。

这样交换至少需要3个分组,因此称之为TCP的三路握手。图2-2展示了所交换的3个分节。

图2-2给出的客户的初始序列号为J,服务器的初始序列号为K。ACK中的确认号是发送这个ACK的一端所期待的下一个序列号。因为SYN占据一个字节的序列号空间,所以每一个SYN的ACK中的确认号就是该SYN的初始序列号加1。类似地,每一个FIN(表示结束)的ACK中的确认号为该FIN的序列号加1.

 

TCP选项

每一个SYN可以含有多个TCP选项。下面是常用的TCP选项。

  • MSS选项。发送SYN的TCP一端使用本选项通告对端它的最大分节大小即MSS,也就是它在本连接的每个TCP分节中愿意接受的最大数据量。发送端TCP使用接收端的MSS值作为所发送分节的最大大小。
  • 窗口规模选项。TCP连接任何一端能够通告对端的最大窗口大小是65535,因为在TCP首部中相应的字段占16位。
  • 时间戳选项。这个选项对于高速网络连接时必要的,它可以防止由失而复现的分组可能造成的数据损坏。

TCP 连接终止

TCP建立一个连接需3个分节,终止一个连接则需要4个分节。

(1)某个应用进程首先调用close,我们称该端执行主动关闭。该端的TCP于是发送一个FIN分节,表示数据发送完毕。

(2)接收到这个FIN的对端执行被动关闭。这个FIN由TCP确认。它的接收也作为一个文件结束符传递给接收端应用进程,因为FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。

(3)一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。

(4)接收这个最终FIN的原发送端TCP确认这个FIN。

既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节。我们使用限定词“通常”是因为:某些情形下步骤1的FIN随数据一起发送;另外,步骤2和步骤3发送的分节都出自执行被动关闭那一端,有可能被合并成一个分节。图2-3展示了这些分组。

类似SYN,一个FIN也占据1个字节的序列号空间。因此,每个FIN的ACK确认号就是这个FIN的序列号加1.

在步骤2和步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的。这称为半关闭。

当套接字被关闭时,其所在端TCP各自发送一个FIN。我们在图中指出,这是由应用进程调用close而发生的,不过需认识到,当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所以打开的描述符都被关闭,这也是导致仍然打开的任何TCP连接上也发出一个FIN。

图2-3展示了客户执行主动关闭的情形,不过我们指出,无论是客户还是服务器,任何一端都可以执行主动关闭。通常情况是客户执行主动关闭,但是某些协议却是由服务器执行主动关闭。

 

TCP状态转换图

TCP涉及连接建立和连接终止的操作可以用状态转换图来说明,如图2-4所示。

TCP为一个连接定义了11种状态,并且TCP规则规定如何基于当前状态及在该状态下所接收的分节从一个状态转换到另一个状态。举例来说,当某个应用进程在CLOSED状态下执行主动打开时,TCP将发生一个SYN,且新的状态是SYN_SENT。如果这个TCP接着接收到一个带ACK的SYN,它将发送一个ACK,且新的状态是ESTABLISHED。这个最终状态是绝大多数数据传送发生的状态。

自ESTABLISHED状态引出的两个箭头处理连接的终止。如果某个应用进程在接收到一个FIN之前调用close(主动关闭),那就转换到FIN_WAIT_1状态。但如果某个应用进程在ESTABLISHED状态期间接收到一个FIN(被动关闭),那就转换到CLOSE_WAIT状态。

我们用粗实现表示通常的客户状态的转换,用粗虚线表示通常的服务状态转换。图中还注明存在两个我们未曾讨论的转换:一个同时打开,发生在两端几乎同时发送SYN并且这两个SYN在网络中交错的情形下,另一个为同时关闭,发生在两端几乎同时发送FIN的情形下。

 

观察分组

图2-5展示一个完整的TCP连接所发生的实际分组交换情况,包括连接建立、数据传送和连接终止3个阶段。图中还展示了每个端点所历经的TCP状态。

本例中的客户通告一个值为536的MSS(表明该客户只实现了最小重组缓冲区大小),服务器通告一个值为1460(以太网上IPV4的典型值)。不同方向上MSS值不相同不成问题。

一旦建立一个连接,客户就构造一个请求并发送给服务器。这里我们假设该请求适合于单个TCP分节(即请求大小小于服务器通告的值为1460字节的MSS)。服务器处理该请求并发送一个应答,我们假设该应答也适合当个分节(本例小于536字节)。图中使用粗箭头表示这两个数据分节。注意,服务器对客户请求的确认是伴随其应答发送的。这种做法称为捎带,它通常在服务器处理请求并产生应答的时间少于200ms时发送。如果服务器耗用更长时间,譬如1s,那么我们将看到先是确认后是应答。

图中随后展示的是终止连接的4个分节。注意,执行主动关闭的那一端(本例子中为客户)进入TIME_WAIT状态。

图2-5中值得注意的是,如果该连接的整个目的仅仅是发送一个单分节的请求和接受一个单分节的应答,那么使用TCP有8个分节的开销。如果改用UDP,那么只需交换两个分组:一个承载请求,一个承载应答。然而从TCP切换到UDP将丧失TCP提供给应用进程的全部可靠性,迫使可靠服务的一大堆细节从传输层转移到应用进程。TCP提供的另一个重要特性及拥塞控制也必须由UDP应用进程来处理。尽管如此,我们仍然需要知道许多网络应用是使用UDP构建的,因为它们需要交换的数据量较少,而UDP避免了TCP连接建立和终止所需的开销。

 

TIME_WAIT 状态

在图2-4中我们看到执行主动关闭的那端经历了这个状态。该端点停留在这个状态的持续时间是最长分节生命期的两倍,有时称之为2MSL。

TIME_WAIT状态有两个存在的理由:

(1)可靠地实现TCP全双工连接的终止;

(2)允许老的重复分节在网络中消逝。

第一个理由可以通过查看图2-5并假设最终的ACK丢失了来解释。服务器将重新发送它的最终那个FIN,因此客户必须维护状态信息,以允许它重新发送那个ACK。要是客户不维护状态信息,它将响应以一个RST(另外一种类型的TCP分节),该分节将被服务器解释成一个错误。如果TCP打算执行所有必要的工作以彻底终止某个连接上两个方向上的数据流(即全双工关闭),那么它必须正确处理连接终止序列4个分节中任何一个分节丢失的情况。本例子也说明了为什么执行主动关闭的那一端是处于TIME_WAIT状态的那一端:因为可能不得不重传最终那个ACK的就是那一端。

为理解存在TIME_WAIT状态的第二个理由,我们假设在12.106.32.154的1500端口和206.168.112.219的21端口之间有一个TCP连接。我们关闭这个连接,过一段时间后在相同的IP地址和端口直接建立另一个连接。后一个连接称为前一个连接的化身,因为它们的IP地址和端口号都相同。TCP必须防止来自某个连接的老的重复分组在该连接已终止后再现,从而被误解成属于同一连接的某个新的化身。为做到这一点,TCP将不给处于TIME_WAIT状态的连接发起新的化身。既然TIME_WAIT状态的持续时间是MSL的2倍,这就足以让某个方向上的分组最多存活MSL秒即被丢弃,另一个方向上的应答最多存活MSL秒也被丢弃。通过实施这个规则,我们就能保证每成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已在网络中消逝了。

时间: 2024-10-13 09:05:01

TCP 连接的建立和终止的相关文章

《UNIX网络编程 卷1:套接字联网API(第3版)》——2.6 TCP连接的建立和终止

2.6 TCP连接的建立和终止 为帮助大家理解connect.accept和close这3个函数并使用netstat程序调试TCP应用,我们必须了解TCP连接如何建立和终止,并掌握TCP的状态转换图. 2.6.1 三路握手建立一个TCP连接时会发生下述情形. (1)服务器必须准备好接受外来的连接.这通常通过调用socket.bind和listen这3个函数来完成,我们称之为被动打开(passive open). (2)客户通过调用connect发起主动打开(active open).这导致客户T

基础教程:TCP连接的建立和释放

TCP首部格式 先看TCP报文段的格式,如下; TCP报文段首部的前20个字节是固定的,后面有4N字节是根据需要而增加的选项.因此TCP报文段的最小长度为20个字节. 首部固定部分的各字段的意义如下: 1.源端口和目的端口:加上IP首部的源IP地址和目的IP地址,确定唯一的一个TCP连接.另外通过目的端口来决定TCP将数据报交付于那个应用程序,从而实现TCP的分用功能. 2.序号:占4个字节,序号的范围为[0,4284967296].由于TCP是面向字节流的,在一个TCP连接中传送的字节流中的每

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

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

TCP/IP之TCP连接的建立与中止状态分析

TCP连接的建立可以简单的称为三次握手,而连接的中止则可以叫做四次握手. 1.连接的建立: c端发起请求同步(用SYN段等于1的TCP报文),确认某个端口是否监听: s端应答(用ACK段等于1的TCP报文), c端收到s端的ACK,并回应s端一个ACK给s端: 经过上面三步连接的建立完成.这就叫做三次握手: 2.连接的中止:(TCP中有half-close,这是因为TCP的连接是全双工(可以同时发送和接收)连接,关闭的时候就需要在两个方向上都进行关闭,否则就是half-close) c端发起关闭

linux网络编程之TCP/IP基础(四) TCP连接的建立和断开、滑动窗口

一.TCP段格式: TCP的段格式如下图所示 源端口号与目的端口号 源端口号和目的端口号,加上IP首部的源IP地址和目的IP地址唯一确定一个TCP连接. 序号 序号表示在这个报文段中的第一个数据字节序号. 确认号 仅当ACK标志为1时有效.确认号表示期望收到 的下一个字节的序号. 头部长度 4位,TCP头部最多60个字节,最少20个字节 保留位 6位,必须为 0 6个标志位 URG-紧急指针有效 ACK-确认序号有效 PSH-接收方应尽快将这个报文段交给应用层 RST- 连接重置 SYN-同步序

TCP 连接断连问题剖析

在官方的正式文档中,TCP/IP 协议簇也称为国际互联网协议簇.TCP/IP 协议簇是目前使用最为广泛的全球互联网技术,其分层结构如图 1 所示: 图 1. TCP/IP 协议簇分层结构   如图 1 所示,数据链路层主要负责处理传输媒介等众多的物理接口细节:网络层负责处理数据分组在网络中的活动,包括上层数据报文的分割.选路 phost2008-08-21T00:00:00 等:传输层则负责为两台主机提供端到端的通信:应用层将负责处理应用程序的特定细节.其中,IP 协议是网络层的核心协议,用来提

TCP连接状态详解

tcp状态:   LISTEN:侦听来自远方的TCP端口的连接请求 SYN-SENT:再发送连接请求后等待匹配的连接请求 SYN-RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认 ESTABLISHED:代表一个打开的连接 FIN-WAIT-1:等待远程TCP连接中断请求,或先前的连接中断请求的确认 FIN-WAIT-2:从远程TCP等待连接中断请求 CLOSE-WAIT:等待从本地用户发来的连接中断请求 CLOSING:等待远程TCP对连接中断的确认 LAST-ACK:等待

ESFramework介绍之(10)-- Tcp连接池

    凡是带有"池"的,比如数据库连接池.对象池.缓冲区池(后面可以看到IBuffPool)等等,都是为了避免资源的反复创建/销毁所带来的开销.需要为哪些资源对象建立"池"了?这些资源对象通常符合下面几个特性:(1)在应用中需要反复的被创建/销毁.(2)创建/销毁的开销比较大(3)应用中给定时刻,对该资源对象的数量要求比较大(4)资源对象最好是无状态的(Stateless),这样方便直接复用     AS(回顾)将所有的功能服务请求转发给为该AS提供服务的FS群中

协议森林09 爱的传声筒 (TCP连接)

作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁任何形式转载.   在TCP协议与"流"通信中,我们概念性的讲解了TCP通信的方式.可以看到,TCP通信最重要的特征是:有序(ordering)和可靠(reliable).有序是通过将文本流分段并编号实现的.可靠是通过ACK回复和重复发送(retransmission)实现的.这一篇文章将引入TCP连接(connection)的概念.   TCP连接 网络层在逻辑上提供了端口的概念.一个IP地址可以有