TCP的3次握手和4次挥手

TCP的3次握手和4次挥手

标签(空格分隔): 找工作


TCP Flags:

TCP首部中有6个标志比特,主要用于操控TCP的状态机的,依次为URG, ACK, PSH, RST, SYN, FIN,每个标志位的含义如下:

  • URG:此标志表示TCP包的紧急指针域有效,用来保证TCP连接不被终端,并且督促中间层设备要尽快处理这些数据;
  • ACK:此标志表示应答有效,1的时候表示应答有效,反之为0;
  • PSH:此标志位表示Push操作。就是说数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队;
  • RST:此标志位表示复位请求。用来复位那些产生错误的连接,也用来拒绝错误和非法的数据包;
  • SYN:表示同步序号,用来建立连接。SYN与ACK搭配使用,
  • 当连接请求的时候,SYN=1,ACK=0;
  • 当连接被响应的时候,SYN=1,ACK=1;
  • FIN:表示发送端已经达到数据末尾,也就是双方的数据传送完成,没有数据可以传送了。

此处输入图片的描述

3次握手

TCP四面向连接的,双方在发送数据之前要先建立一个可靠的连接。三次握手的目的是同步连接双方的序列号和确认号并交换TCP窗口大小信息。

  1. 第一次握手:建立连接。客户端发送请求报文段,SYN=1,Sequence Number为x;然后客户端进入SYN_SEND状态,等待服务器确认;
  2. 第二次握手:服务器收到SYN报文段,需要对这个报文段进行确认,设置Acknowledge Number为x+1;同时自己也要打出SYN请求信息,SYN=1,Sequence Number设为y,服务器进入SYN_RECV状态;
  3. 第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledge Number设为y+1,并发送Ack报文段,这个报文段发送以后,客户端和服务器都进入ESTABLISHED状态,完成了TCP的三次握手。

为什么要3次握手?

防止已失效的连接请求报文段突然又传送到了服务端,产生错误。
什么意思呢?
设想这样一种情况:client发出的第一个请求报文段并没有丢失,而是在网络中滞留了,以致于延误到连接释放以后的某个时间才到达server。本来这是一个早已经失效的请求,但server收到以后误以为是client又心法了一个连接请求,就会同意连接,发送ack确认报文,这时:

  • 如果是2次握手,这样client和server之间就建立起了一条信道,并一直等待client发送数据过来,server就会浪费很多资源;
  • 而如果是3次握手,client收到server发送的对自己已经失效的报文段的ack确认报文,边不予理睬。server由于没有收到确认,就知道client并没有请求建立连接了。
    所以,3次握手的目的就是,为了防止server一直等待而浪费资源。

4次挥手

当客户端和服务器数据传送完毕后,肯定要断开他们之间的连接,而断开连接时需要4次挥手:

  1. 第一次挥手:客户端设置Sequence Number和Acknowledge Number,并向服务器发送一个FIN报文段,这是,客户端进入FIN_WAIT_1状态,表示客户端没有数据要发送给服务器了;
  2. 第二次挥手:服务器收到了客户端发来的FIN报文段,向客户端发送一个ACK(Seq+1)报文段,客户端进入FIN_WAIT_2状态,也就是服务器同意客户端的关闭请求;
  3. 第三次挥手:服务器向客户端发送FIN报文段,请求关闭连接,同时服务器进入CLOSE_WAIT状态;
  4. 第四次挥手:客户端收到服务器发送的FIN报文段,向服务器发送ACK报文段,然后客户端进如TIME_WAIT状态;服务器收到客户端发来的ACK报文段之后,就关闭连接;此时,客户端等待2MSL后依然没有收到回复,则证明服务器已正常关闭,所以客户端也可以关闭连接了。

TCP是全双工模式,当客户端发出FIN报文段时,只是表示客户端没有数据要发送了,所以客户端向服务器发送FIN,告诉服务器它的数据已经全部发送完了;但这个时候客户端还是可以接收来自服务器的数据;
当服务器返回ACK报文段时,表示它已经知道客户端没有数据发送了,但服务器还是可以向客户端发送数据的;
当服务器发送FIN给客户端时,表示服务器也没有数据要发送了,之后客户端收到服务器的FIN报文段时也会返回ACK报文段,结束这次传输。

为什么要4次挥手?

  • FIN_WAIT_1:当SOCKET在ESTABLISHED状态时,它想主动关闭连接,想对方发送了FIN请求,于是该SOCKET进入FIN_WAIT_1状态;
  • FIN_WAIT_2:当收到对方回应的ACK报文段时,就会进入到FIN_WAIT_2状态。该状态下的SOCKET表示半连接,即有以防要求close连接。但另外还告诉主动方,我这边还有一点数据要发送,稍后再关闭连接。
  • CLOSE_WAIT:等待关闭。当主动方发送一个FIN报文段过来时,被动方毫无疑问要发送一个ACK确认报文段,被动方就进入到CLOSE_WAIT状态。然后看自己是否还有数据要发送,如果也没有数据了,则也可以发送FIN报文段给主动方,关闭连接;
  • LAST_ACK:指被动方发送了FIN报文段之后,等待对方的ACK时的状态;
  • TIME_WAIT:表示收到了对方的FIN报文段,并发出了ACK报文,等待2MSL后就可以回到CLOSED状态了。

[参考链接]
http://www.jellythink.com/archives/705

原文地址:https://www.cnblogs.com/little-YTMM/p/5687290.html