原创

网络

TCP的三次握手和四次挥手

发表于 2021-12-02

更新于 3年前

阅读量: 642

温馨提示

该文章距离上次更新已经过去了 1246 天,文章内容可能已经过时。

TCP的三次握手是用来建立连接的,四次挥手是用来断开连接的

三次握手

TCP的三次握手和四次握手

两台计算机要进行通信,首先要做的就是确认两台计算的收和发的能力,三次握手就是用来确认两台计算机是否都具备收和发的能力

初始状态

客户端和服务端都处于CLOSED状态,客户端主动打开链接,服务端被动打开链接进入LISTEN状态

第一次握手

第一次握手主要传递两个信息:

  1. 请求建立连接:在实际链接中,通常用SYN = 1表示
  2. 发出一个序列号(client_isn):在实际链接中,通常用seq=n表示,n为一个随机数,这个序列号的作用是如果服务端返回了一个该序列号+1的确认应答号,说明服务端是可以接收到信息的

发送完信息后,客户端处于SYN-SEND状态,第一次握手让服务端知道客户端能发出信息

第二次握手

第二次握手主要传递三个信息:

  1. 同意建立链接:SYN = 1
  2. 发出一个确认应答号ack:在实际链接中,ack为客户端发出的序列号seq + 1,这个确认应答号是为了告诉客户端,自己能接收到信息
  3. 发出自己的序列号:seq = n,n为一个随机数,这个序列号的作用是为了在第三次握手的时候,如果客户端返回了该序列号+1的确认应答号,说明客户端也具备接收信息的能力

发送完信息后,服务端处于SYN-RECEIVED状态,第二次握手让客户端知道了服务端能接收消息也能发出消息,此时,服务端还需要知道客户端是否具备接收消息的能力,所以需要第三次握手

第三次握手

第三次握手也传递三个信息:

  1. 表示开始发送:SYN = 0
  2. 确认应答号ack:在实际链接中,ack为服务端发出的序列号seq + 1,告诉服务端自己可以接收到消息
  3. 发出该信息的序列号:seq = 最开始发出的序列号 + 1

第三次握手后,服务端知道了客户端有接收消息的能力,此时,客户端和服务端都知道了彼此有了发送和接收消息的能力,此时客户端和服务端都进入ESTABLISHED状态,通讯开始。

四次挥手

TCP的三次握手和四次握手

在发送完数据后,客户端和服务器都需要知道数据是否已经发送完且已经接收完,所以四次挥手要做的就是确认数据是否已经发送和接收完毕,分别是:发完了、知道发完了、接收完了、知道接收完了

第一次挥手

在客户端发送完数据之后,不能直接断开链接,因为服务端并不知道数据已经发送完了,所以第一次挥手就是告诉服务端,数据已经发送完毕,发送完信息后,客户端进入FIN_WAIT_1状态

第二次挥手

在服务端接收到客户端的信息后,会返回給客户端一个ack应答号,告诉客户端自己已经知道客户端数据发送完毕,发送完之后服务器进入CLOSE_WAIT状态,客户端在接收到服务端发出的ack应答报文后,进入FIN_WAIT_2状态

第三次挥手

在服务端接收完数据后,会再像客户端发送一个FIN报文,告诉客户端自己已经接收完数据,直接服务端进入LAST_ACK状态

第四次挥手

客户端在接收到服务端的FIN报文后,会给服务端返回一个ack报文,之后客户端进入TIME_WAIT状态
服务端接收到这个ack报文后,会进入CLOSED状态,此时服务端完成了连接的关闭
客户端在经过 2MSL 后,自动进入 CLOSED 状态,至此客户端也完成连接的关闭。

为什么客户端在TIME-WAIT阶段要等2MSL?

MSL(Maximum Segment Lifetime)指的是一段TCP报文在传输过程中的最大生命周期
由于TCP的连接是全双工的,所以需要双方分别释放掉对方的连接,单独一方的连接释放,只能代表不能再向对方发送数据,连接处于的是半释放的状态,所以客户端在最后发送ack报文后,如果在2MSL内没有继续收到服务端发来的FIN报文,则说明服务端的连接已经成功关闭,其中的1MSL是客户端发送最后ack到服务端的时候,另外的1MSL则是如果服务端因为某些原因没有收到客户端最后发来的ack报文,则会再发送一个FIN报文给客户端,所以一共需要等待2MSL的时间
如果因为某些原因,服务端没有接收到来自客户端最后的ack报文,则会重新发送一个FIN报文给客户端,客户端收到该FIN报文后,会重新发送一个ack报文给服务端,这时计时器就会重置,客户端需要重新等待2MSL的时间
因此,客户端的连接一定会比服务端的连接晚关闭2MSL的时间

如果已经建立了连接,但是客户端突然故障了怎么办?

如果客户端突然故障,服务端不可能一直等下去,因为TCP还设有一个保活计时器,服务端在每次接收到客户端的信息时,都会重置这个计时器,时长通常为2小时,如果2小时候还没有接收到客户端的信息,服务端就会发送一个探测报文,之后每隔75秒发送一次,如果连续发送10次客户端仍然没有回应,则服务端判断客户端已经故障,接着关闭连接。

为什么需要第三次握手?

三次握手的目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误
有一种情况,客户端发出了一个连接请求,这个连接请求并没有丢失,而是在某个网络节点长时间滞留,以至于到了连接释放之后才到达服务端,虽然这个报文是一个失效的报文,但是服务端会把这个报文当成是客户端发起的一个新的请求连接,如果只有两次握手,那么服务端在返回一个确认报文后,就会建立连接,开始等待客户端发送来的数据,但是此时客户端并没有发起连接,所以不会理会服务端发来的确认报文,这时候服务端的资源就白白浪费了,但是如果有第三次握手,服务端没有收到来自客户端的确认,就知道客户端并没有发起请求连接,就不会建立连接。

评论
0/100
0/100
0/100
0/250
暂无评论