TCP连接的建立与终止

来源:互联网 发布:大富豪3.4源码 编辑:程序博客网 时间:2024/05/20 23:35
一个TCP连接由一个4元组构成,它们分别是两个IP地址,两个端口号。即一个TCP连接是由一对端点或套接字构成,其中通信的每一端都由一对(IP地址,端口号)所唯一标识。
一个TCP连接通常分为3个阶段:启动、数据传输和退出


TCP打开与关闭

下图是一个典型的TCP连接的建立和关闭过程:




为了建立一个TCP连接,需要完成以下步骤:

1.主动开启者(客户端)发送一个SYN报文段(即一个在TCP头部的SYN字段位置的TCP/IP数据包),并指明自己想要连接的端口号和它的客户端初始序列号(即为ISN(c))。通常,客户端还会借此发送一个或多个选项。客户端发送的这个SYN报文段称作段1。
2.服务器也发送自己的SYN报文段作为响应,并包含了它的初始序列号(ISN(s))。该段称作段2。另外,为了确认客户端的SYN,服务器将其包含的ISN(c)数值加1作为返回的ACK数值。因此,每发送一个SYN,序列号就会自动加1。这样如果出现丢失的情况,该SYN段将会重传。
3.为了确认服务器的SYN,客户端将ISN(s)的数值加1后作为返回的ACK数值,这称作段3。


通过发送上述三个报文段就能完成一个TCP连接的建立,通常称为三次握手。三次握手的目的不仅在于让通信双方了解一个连接正在建立,还在于利用数据包的选项来承载特殊的信息,交换初始序列号。



TCP协议规定通过发送一个FIN段来发起关闭操作,只有当连接双方都完成关闭操作后,才构成一个完整关闭:

1.连接的主动关闭者发送一个FIN段指明接受者希望看到自己当前的序列号K。FIN段还包含了一个ACK段用于确认对方最近一次发来的数据(记为L)。
2.连接的被动关闭者将K的数值加1作为响应的ACK值,以表明它已经成功接收到主动关闭者发送的FIN。此时,上层的应用程序会被告知连接的另一端已经提出了关闭的请求。通常,这将导致应用程序发起自己的关闭操作。接着,被动关闭者将身份转变为主动关闭者,并发送自己的FIN。该报文段的序列号为L。
3.为了完成连接的关闭,最后发送的报文段还包含一个ACK用于确认上一个FIN。值得注意的是,如果出现FIN丢失的情况,那么发送方将重新传输直到接收到一个ACK确认为止。
综上所述,建立一个TCP连接需要3个报文段,而关闭一个TCP连接需要4个报文段。


TCP半关闭
伯克利套接字的API提供了半关闭操作,应用程序只需要调用shutdown()函数来代替基本的close()函数。
首先发送的两个报文段与TCP正常关闭完全相同:初始者发送的FIN,接着是接收者回应该FIN的ACK。由于接收到半关闭的一方仍能发送数据,当接收半关闭一方完成数据发送后,它将会发送一个FIN来关闭本方的连接,同时向发起半关闭的应用程序发出一个文件尾指示。当第2个FIN被确认后,整个连接完全关闭。

TCP同时打开与关闭
一个同时打开过程需要交换4个报文段,比普通的三次握手增加了一个。由于通信双方都扮演了客户端与服务器的角色,因此不能够将任何一方称作客户端或服务器。

TCP状态转换图




TCP状态转换图。箭头表示因报文段传输、接收以及计时器超时而引发的状态装换。红色粗箭头表示典型的客户端行为,绿色虚箭头表示典型的服务器行为。

初始化时,TCP从CLOSED状态启动。通常根据是执行主动打开操作还是被动打开操作,TCP将分别快速转换到SYN_SENT或LISTEN状态。
导向ESTABLISHED状态的两种转换与打开一个连接相关,从ESTABLISHED状态导出的两种转换则用于终止一个连接。ESTABLISHTED是通信双方传输数据的状态。
FIN_WAIT_1、FIN_WAIT_2以及TIME_WAIT状态用一个方框括起来(至少是部分被括起来),称作主动关闭。另外两个状态(CLOSE_WAIT、LAST_ACK)被括起来,称为被动关闭。