TCP 运输连接管理
运输连接有三个阶段:
连接建立
数据传送
连接释放
三次握手
TCP 建立连接的过程叫做握手。
握手需要在客户和服务器之间交换三个 TCP 报文段。称之为三报文握手。采用三报文握手主要是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。
A 的 TCP 向 B 发出连接请求报文段,其首部中的同步位 SYN = 1,并选择序号 seq = x,表明传送数据时的第一个数据字节的序号是 x。
B 的 TCP 收到连接请求报文段后,如同意,则发回确认。B 在确认报文段中应使 SYN = 1,使 ACK = 1,其确认号 ack = x + 1,自己选择的序号 seq = y。
A 收到此报文段后向 B 给出确认,其 ACK = 1,确认号 ack = y + 1。A 的 TCP 通知上层应用进程,连接已经建立。
B 的 TCP 收到主机 A 的确认后,也通知其上层应用进程:TCP 连接已经建立。
* 第一次握手:建立连接时,客户端发送 syn 包(syn = j)到服务器,
并进入 SYN_SENT 状态,等待服务器确认;
SYN:同步序列编号(Synchronize Sequence Numbers)。
* 第二次握手:服务器收到 syn 包,必须确认客户的 SYN(ack = j + 1),
同时自己也发送一个 SYN 包(syn = k),即 SYN + ACK 包,
此时服务器进入 SYN_RECV 状态;
* 第三次握手:客户端收到服务器的 SYN + ACK 包,
向服务器发送确认包 ACK (ack = k + 1),此包发送完毕,
客户端和服务器进入 ESTABLISHED(TCP 连接成功)状态,完成三次握手。
握手的目的是什么?
握手的目的是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。比如一个客户端发出一个连接请求报文虽然没有丢失,但是由于一些原因在在某个网络节点中长时间滞留,以至于在断开连接后才到达服务端。这本身就是一个已经失效的报文。但是服务器误以为是客户端的又一个新的请求。假设没有三次握手那么只要服务端发出确认链接就建立了。由于客户端也没有给服务端发请求,因此也不回复服务端的确认。但是服务端确认为新的连接开始了,等待客户端发数据。这样就容易造成服务端的资源的浪费。采用三次握手可以防止这种情况发生。
四次挥手
数据传输结束后,通信的双方都可释放连接。TCP 连接释放过程是四报文握手。
数据传输结束后,通信的双方都可释放连接。现在 A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。A 把连接释放报文段首部的 FIN = 1,其序号 seq = u,等待 B 的确认。
B 发出确认,确认号 ack = u + 1,而这个报文段自己的序号 seq = v。TCP 服务器进程通知高层应用进程。从 A 到 B 这个方向的连接就释放了,TCP 连接处于半关闭状态。B 若发送数据,A 仍要接收。
若 B 已经没有要向 A 发送的数据,其应用进程就通知 TCP 释放连接。
A 收到连接释放报文段后,必须发出确认。
在确认报文段中 ACK = 1,确认号 ack = w + 1,自己的序号 seq = u + 1。
对于一个已经建立的连接,TCP使用改进的三次握手来释放连接
(使用一个带有 FIN 附加标记的报文段)。TCP 关闭连接的步骤如下:
* 第一步,当主机 A 的应用程序通知 TCP 数据已经发送完毕时,
TCP 向主机 B 发送一个带有 FIN 附加标记的报文段(FIN 表示英文 finish)。
* 第二步,主机 B 收到这个 FIN 报文段之后,并不立即用 FIN 报文段回复主机 A,
而是先向主机 A 发送一个确认序号 ACK,同时通知自己相应的应用程序:
对方要求关闭连接(先发送 ACK 的目的是为了防止在这段时间内,对方重传 FIN 报文段)。
* 第三步,主机 B 的应用程序告诉 TCP:
我要彻底的关闭连接,TCP 向主机 A 送一个 FIN 报文段。
* 第四步,主机 A 收到这个 FIN 报文段后,
向主机 B 发送一个 ACK 表示连接彻底释放。
为什么 A 必须等待 2MSL 的时间?
为了保证 A 发送的最后一个 ACK 报文段能够到达 B。
防止 “已失效的连接请求报文段” 出现在本连接中。A 在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段,都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。
为什么握手三次,挥手四次?
三次握手
因为要保证信道的可靠,就需要双方沟通并且达成一致。而要解决这个问题 3 次是最小值。四次挥手
因为 TCP 连接是全双工的,因此每个方向都必须单独的断开连接客户端申请断开连接,只是不再发送数据,还能接收数据。需要等待服务端将数据发送完毕后,等待服务端申请断开连接。