了解TCP连接中的3次握手与4次挥手

Posted SSimeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了了解TCP连接中的3次握手与4次挥手相关的知识,希望对你有一定的参考价值。

TCP简介:
传输层控制协议(TCP Transport Control Protocol),是一种面向连接的、可靠的、基于字节流的传输层通信协议,是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。

1. 报文的格式

TCP在传输的过程中是以TCP报文的格式,那么我们了解下什么是报文呢?
在这里插入图片描述介绍:

  1. 源端口: 16位,表示数据从哪个进程来

  2. 目的端口:16位,表示数据到哪个进程去

  3. 序号: 32位,TCP报文段中的数据部分,每一个字节都有它的序号(递增)。根据控制标志中的SYN是否为1,序号表达不同的含义:

    (1)SYN = 1: 当前为连接建立阶段,此时的序号为初始序号(ISN)。当数据传输正式开始时,数据的第一个字节的序号为 ISN + 1

    (2)SYN = 0: 当前报文段中,数据部分的第一个字节的序号。

  4. 确认序号: 32位,当控制标志的ACK为1时,表示发送方希望收到的下一个报文段的序号。一旦连接建立成功,ACK值一直为1。

  5. 数据偏移: 4位,TCP报文段的首部长度,单位是4字节。TCP报文段的数据的起始处,距离TCP报文段的起始处 的偏移量。4个字节最大能表示的数字是15,所以首部最大60字节。

  6. 保留: 6位,作为后续用途,必须是0。

  7. 控制标志: 一共有6个控制标志,其中SYN/ACK、FIN/ACK主要用于连接的建立、断开阶段。

URG: 当置为1时,表示紧急指针字段有效;
ACK:确认序号字段有效;
PSH:接收方应立即把这个报文段交给应用层;
RST: 重建连接;
SYN:同步序号,用于建立连接;
FIN: 发送端不再发送数据;

  1. 窗口大小:16位,允许对方发送的数据量。告诉对方自己缓冲区还能容纳多少字节,用来控制对方发送数据的速度。

  2. 检验和:16位,发送端对TCP首部、数据进行CRC运算得出的结果。接收端收到数据后,对接收到的TCP报文段的首部、数据进行CRC运算,并跟TCP首部中的校验和进行对比,确保数据在传输过程中没有损坏。

  3. 紧急指针:16位,仅在URG=1时才生效,它的值是一个偏移量,和序号字段中的值相加得到紧急数据最后一个字节的序号。

2. 建立TCP连接(三次握手)

在这里插入图片描述
(1)第一次握手:建立连接时,客户端发送SYN包,报文首部中的同步序号SYN=1,同时选择一个初始序列号 seq=x 到服务器,并进入SYN_SENT状态,等待服务器确认。

(2)第二次握手:TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN_RCVD(同步收到)状态。

(3)第三次握手:客户端收到服务器的SYN+ACK包后,还要向服务器发送确认报文(ACK=1,ack=y+1,自己的序列号seq=x+1),此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态此包发送完毕,完成三次握手。

3. 为什么需要三次握手呢?

这是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

客户端发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达服务器。本来这是一个早已失效的报文段。但服务器收到此失效的连接请求报文段后,就误认为是客户端再次发出的一个新的连接请求。于是就向客户端发出确认报文段,同意建立连接。客户端不会向服务器的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。

4. TCP断开连接的过程(四次挥手)

数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。
在这里插入图片描述
❶ 客户端发出连接断开报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=x,此时,客户端进入FIN-WAIT-1(终止等待1)状态。

❷ 服务器收到连接释放报文,发出确认报文,ACK=1,ack=x+1,并且带上自己的序列号seq=z,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

❸ 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=x+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=y,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

❹客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=y+1,而自己的序列号是seq=x+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

5. 为什么要等待2MSL(最长报文段寿命)

(1) 客户端发送完最后一个ACK包后无法确认对方是否有收到这个ACK包,所以2MSL的时间能保证如果对方没收到会重发第三次挥手的FIN包,且这个包有足够的时候发送回来。
(2)如果在这个时间内客户端还没收到重发的FIN包,便可以证明对方已收到该ACK包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。

6.为什么连接的时候是三次握手,关闭的时候却是四次握手?

  1. 因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。
  2. 但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。
  3. 只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

以上 就是我对TCP连接的理解,请各位朋友指教!!!

以上是关于了解TCP连接中的3次握手与4次挥手的主要内容,如果未能解决你的问题,请参考以下文章

TCP协议的3次握手与4次挥手过程详解

TCP为啥需要3次握手与4次挥手

理论经典:TCP协议的3次握手与4次挥手过程详解

TCP协议的3次握手与4次挥手过程详解

TCP协议的3次握手与4次挥手过程深度详解

TCP协议中的3次握手和4次挥手