TCP三次握手和四次挥手

由 RPF 发布

TCP

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
简单来说,它的作用就是将数据流从一台主机可靠地传输到另一台主机。
参考:
https://blog.csdn.net/weixin_43828291/article/details/124081265
https://www.cnblogs.com/AhuntSun-blog/p/12028636.html

三次握手(Three-Way Handshake)

  • 第一次握手:起初两端都处于 CLOSED 关闭状态,Client 将标志位 SYN 置为 1,随机产生一个值 seq = x,并将该数据包发送给 Server,Client 进入 SYN-SENT 状态,等待 Server 确认。
  • 第二次握手:Server 收到数据包后由标志位 SYN = 1 得知 Client 请求建立连接,Server 将标志位 SYN 和 ACK 都置为 1,ack = x + 1,随机产生一个值 seq = y,并将该数据包发送给Client以确认连接请求,Server 进入 SYN-RCVD 状态,此时操作系统为该 TCP 连接分配 TCP 缓存和变量。
  • 第三次握手:Client 收到确认后,检查 seq 是否为 x + 1,ACK 是否为 1,如果正确则将标志位 ACK 置为 1,ack = y + 1,并且此时操作系统为该 TCP 连接分配 TCP 缓存和变量,并将该数据包发送给 Server,Server 检查 ack 是否为 y + 1,ACK 是否为 1,如果正确则连接建立成功,Client 和 Server 进入 established 状态,完成三次握手,随后 Client 和 Server 就可以开始传输数据。

为什么要进行第三次握手?

为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器),在传输的过程中,比如客户端发起了SYN=1创建连接的请求(第一次握手)。
如果服务器端就直接创建了这个连接并返回包含SYN、ACK和Seq等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直没有接收到服务器返回的数据包。
客户端可能设置了一个超时时间,时间到了就关闭了连接创建的请求。再重新发出创建连接的请求,而服务器端是不知道的,如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话,服务器端是不知道客户端有没有接收到服务器端返回的信息的。
“第三次握手”是客户端向服务器端发送数据,这个数据就是要告诉服务器,客户端有没有收到服务器“第二次握手”时传过去的数据。若发送的这个数据是“收到了”的信息,接收后服务器就正常建立TCP连接,否则建立TCP连接失败,服务器关闭连接端口。由此减少服务器开销和接收到失效请求发生的错误。

tcp1.png

tcp2.png

四次挥手

所谓的四次挥手即TCP连接的释放(解除)。连接的释放必须是一方主动释放,另一方被动释放。

第一次挥手:Client 的应用进程先向其 TCP 发出连接释放报文段(FIN = 1,序号 seq = u),并停止再发送数据,主动关闭 TCP 连接,进入 FIN-WAIT-1(终止等待1)状态,等待 Server 的确认。

第二次挥手:Server 收到连接释放报文段后即发出确认报文段,(ACK = 1,确认号 ack = u + 1,序号 seq = v),Server 进入 CLOSE-WAIT(关闭等待)状态,此时的 TCP 处于半关闭状态,Client 到 Server 的连接释放。
    注:Client 收到 Server 的确认后,进入 FIN-WAIT-2(终止等待2)状态,等待 Server 发出的连接释放报文段。

第三次挥手:Server 已经没有要向 Client 发出的数据了,Server 发出连接释放报文段(FIN = 1,ACK = 1,序号 seq = w,确认号 ack = u + 1),Server 进入 LAST-ACK(最后确认)状态,等待 Client 的确认。

第四次挥手:Client 收到 Server 的连接释放报文段后,对此发出确认报文段(ACK = 1,seq = u + 1,ack = w + 1),Client 进入 TIME-WAIT(时间等待)状态。此时 TCP 未释放掉,需要经过时间等待计时器设置的时间 2MSL 后,Client 才进入 CLOSED 状态。
tcp3.png
tcp4.png

为什么“握手”是三次,“挥手”却要四次?

TCP建立连接时之所以只需要"三次握手",是因为在第二次"握手"过程中,服务器端发送给客户端的TCP报文是以SYN与ACK作为标志位的。SYN是请求连接标志,表示服务器端同意建立连接;ACK是确认报文,表示告诉客户端,服务器端收到了它的请求报文。
即SYN建立连接报文与ACK确认接收报文是在同一次"握手"当中传输的,所以"三次握手"不多也不少,正好让双方明确彼此信息互通。
TCP释放连接时之所以需要“四次挥手”,是因为FIN释放连接报文与ACK确认接收报文是分别由第二次和第三次"握手"传输的。为何建立连接时一起传输,释放连接时却要分开传输?
建立连接时,被动方服务器端结束CLOSED阶段进入“握手”阶段并不需要任何准备,可以直接返回SYN和ACK报文,开始建立连接。释放连接时,被动方服务器,突然收到主动方客户端释放连接的请求时并不能立即释放连接,因为还有必要的数据需要处理,所以服务器先返回ACK确认收到报文,经过CLOSE-WAIT阶段准备好释放连接之后,才能返回FIN释放连接报文。


暂无评论

发表评论