TCP的三次握手与四次挥手

1.TCP三次握手

tcp是面向连接的协议,是运输层的协议,所以使用tcp在传送数据的时候,必须要建立连接,并且在发送结束后,必须要释放链接。

下图是TCP的链接过程,分为客户端和服务器两部分,下面就来分析一下。


三次握手
  • 默认是两端都是CLOSED(关闭的状态),然后客户A主动打开连接,B被动打开连接,然后B进入了LISTEN状态。
  • A开始发送请求,其中同步SYN设置为1,seq设置为x,x代表传输数据的时候第一个数据字节序号,此时A进入了SYN_SENT状态。
  • B收到A发送的第一个包后,进入了SYN_RCVD的状态,并给A回复确认,确认中SYN = 1,ack= x + 1 (也就是A的seq + 1,告诉A,你该发下一个包了),同时也要给出自己的seq = y,留着给A回复用的,最后还要带ACK = 1,这个来标志是一个回复包。
  • A收到B的确认包后,进入了ESTABLISHED过程,要发送最后一个包,同理ACK = 1 标志回复,seq = x + 1 标志发送B刚才向A请求的x + 1 包 (第3条括号里面内容),ack = y + 1是回复B,我收到了你的序列号为y那个包。
  • B收到后,进入了ESTABLISHED过程,说明三次握手成功。
一些参数的总结

SYN 同步序列编号(Synchronize Sequence Numbers):标志包是一个同步序列包。
ACK (Acknowledgement)即是确认字符:标志是一个确认包。
seq 英文单词Sequence缩写:是序列号的意思,用于放当前包的序列号的。
ack:用于放确认号的。

2. 为什么是三次握手?而不是两次?

主要是为了防止已经失效的连接请求报文段突然又传送到了B,因而产生错误。什么叫做已失效的报文呢?

假如说A发送一个请求报文给B,在网络上长时间滞留……
没有收到B的确认,A重新启动了新的连接,但是这次迅速完成了,并跟B进行了数据发送并释放连接。
然后滞留那家伙就到了B,这时候B以为是新的请求,于是就开始回复,A收到回复之后说,这个我刚才不是收完了么?怎么又来发,于是就不理会B,B一看没有理会,就不管了。
但是要是两次握手呢?A发送,B确认,两方都处于建立状态,A也不请求数据,B就死等,就浪费了很多资源。
所以就有了三次握手。

3. TCP四次挥手

  • 默认A,B都是打开的,首先A请求主动关闭,A从ESTABLISHED状态转到FIN-WAIT-1状态,发送FIN = 1 (代表结束报文)seq序列号为u
  • B收到A的结束报文后,发送回复报文(ACK = 1),回应上一个序列接受成功(ack = u + 1),并且标志新的回复报文序列号是seq = v,发送之后进入了等待关闭状态(CLOSE-WAIT)。
  • A收到了B的等待结束报文,就进入了FIN-WAIT-2阶段,不再发送任何回复报文,等待B发送释放报文段。
  • 此时B发送释放报文,FIN = 1(结束报文), ACK = 1(回复报文),seq = w(报文序列号),ack = u + 1(是一次释放连接过程中的挥手),然后B进入了LAST-ACK状态。
  • A发送回应报文ACK = 1,seq = u + 1(开始发送u + 1报文段),ack = w + 1(确认u报文段已经收到),然后A进入了TIME-WAIT状态,要等待2个MSL时间结束连接,B收到回应报文后立马结束连接。
  • 四次挥手就结束了。

4. 为什么要等待2MSL?

为了保证A发送的最后一个ACK报文能够抵达B,这个ACK报文可能在传输过程中丢失。
下面时如果A回应报文丢失的情况,B就收不到,一直会在LAST-ACK状态等,假如超时了,B认为第三次挥手A没收到才没给我回应,因此会重传第三次挥手,那么A一定要留出2MSL来等待B的重传,从而能够确保B顺利关闭连接,否则会浪费服务器资源。

你可能感兴趣的:(TCP的三次握手与四次挥手)