一、引言
TCP是一个面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。连接创建与终止的状态变化图如下:
二、三次握手建立连接
- 客户端发送一个SYN数据包指明客户端打算连接服务器的端口,初始化序号(ISN)为m。
- 服务器发回包含服务器的ISN作为应答(值为n)。同时,将确认序号设置成客户端ISN+1(m+1)来作为对客户端SYN的确认。
- 客户端发送一个ACK数据包,ack=n+1,作为对服务器的SYN的确认。
1.为什么是三次握手,而不是两次
网络是不可靠的,数据包是可能丢失的
。假设没有第三次确认,客户端向服务端发送了 SYN,请求建立连接。由于延迟,服务端没有及时收到这个包。于是客户端重新发送一个 SYN 包。回忆一下介绍 TCP 首部时提到的序列号,这两个包的序列号显然是相同的。假设服务端接收到了第二个 SYN 包,建立了通信,一段时间后通信结束,连接被关闭。这时候最初被发送的 SYN 包刚刚抵达服务端,服务端又会发送一次 ACK 确认。由于两次握手就建立了连接,此时的服务端就会建立一个新的连接,然而客户端觉得自己并没有请求建立连接,所以就不会向服务端发送数据。从而导致服务端建立了一个空的连接,白白浪费资源。
TCP是双通道,需要双向确定
。只有两次握手,客户端知道了服务器收到了,服务器不知道客户端收到了,联想打电话。通讯系统中的占拜庭将军问题。
2.最大报文段长度
最大报文段长度(MSS)表示TCP传往另一端的最大块数据的长度。当一个连接建立时,连接的双方都要通告各自的MSS。在三次握手的时候SYN的TCP首部中的可选字段确定。以太网的默认长度为1460。
3.
三、四次握手关闭连接(正常状态)
建立一个连接需要三次握手,而终止一个连接要经过4次握手。这由TCP的半关闭(half-close)造成的。一个TCP连接是全双工(即数据在两个方向上能同时传递),因此每个方向必须单独地进行关闭。
- 主动方想要关闭连接,发送FIN包给被动方,序号为m
- 被动方接收到主动方发送的FIN包,知道了对方要关闭连接,发送ACK确认包,序号m+1。主动方连接关闭。
- 等待片刻(处于半关闭状态),在此期间(fin_wait2,close_wait)。被动方发送最后的数据,主动方接收最后的数据。
- 被动方确认要关闭连接,发送FIN包。序号n。
- 主动方等待片刻(接收网络中,还未到达的数据包),发送ACK确认包。序号n+1。到此连接关闭。
1.TCP的半关闭状态
TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。如主动方处于fin_wait2状态。
2.TIME_WAIT状态
TIME_WAIT状态也称为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL( Maximum Segment Lifetime)。它是任何报文段被丢弃前在网络内的最长时间。因为TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。在实际应用中,对 I P数据报TTL的限制是基于跳数,而不是定时器。 在处于2MSL等待状态的socket(客户端IP与端口,服务器IP与端口)不能再被使用。但在实际的使用中,允许一个新的连接请求到达仍处于time_wait状态的连接,只要新的序号大于该连接的前一个连接的最后序号。