tcp三次握手

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

位码即tcp标志位,有6种标示:

  • SYN(synchronous同部位),tcp握手的第一次
  • ACK(acknowledgement 确认位),建立连接时用到的
  • PSH(push) 推送位,若为1,代表要求对方立即传送缓冲区内的其他对应封包
  • FIN(finish结束)
  • RST(reset重置)
  • URG(urgent紧急),为1表示紧急的报文封包
  • SEQ(sequence number)序列号
  • ACK(acknowledge number)确认号

2.1 第一次握手

  • (主机1)标志位:SYN=1
  • 建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

2.2 第二次握手

  • (主机2)标志位:SYN=1;ACK=1
  • 服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器 进入SYN_RECV状态;

2.3 第三次握手

  • (主机1)标志位:ACK=1
  • 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED状态,完成三次握手。

通过这样的三次握手,客户端与服务端建立起可靠的双工的连接,开始传送数据。 三次握手的最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的。

为了保证服务端能收接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手,
为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手。

3.1 第一次分手

  • (主机1)标志位:SYN=1
  • 主机1(可以是客户端 或 服务器端),设置seq=x和ACK=y,向主机2发送一个FIN报文段;
  • 此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;

3.2 第二次分手

  • (主机2)标志位:ACK=1
  • 主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,此时ACK=x+1;
  • 主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;

3.3 第三次分手

  • (主机2)标志位:SYN=1
  • 主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入CLOSE_WAIT状态;

3.4 第四次分手

  • (主机1)标志位:ACK=1
  • 主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;
  • 主机2收到主机1的ACK报文段以后,就关闭连接;
  • 此时,主机1等待2MSL1)后依然没有收到回复,则证明主机2端已正常关闭,那好,主机1也可以关闭连接了。

【注】

  • 在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。
  • 主动关闭方(主机1)的FIN_WAIT_1、FIN_WAIT_2阶段其实都在等待主机2给他发送FIN报文。

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

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。


1)
MSL是Maximum Segment Lifetime,译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等
  • homelab/网络/tcp三次握手.txt
  • 最后更改: 2019/04/16 18:31
  • (外部编辑)