TCP三次握手四次断开及11种状态转变

版权声明:本文为博主原创文章,转载请指明地址。 https://blog.csdn.net/Mr_rsq/article/details/81082127

TCP三次握手四次断开及11种状态转变

  • 置位概念:根据TCP的包头字段,存在三个重要的标识ACK、SYN、FIN
  • ACK:表示验证字段
  • SYN:位数置为1,表示建立TCP连接
  • FIN:位数置为1,表示断开TCP连接

这里写图片描述
建立过程:

  1. 由客户端发送建立TCP连接的请求报文,其中报文中包含seq序列号,是由发送端随机生成的,并且还将报文中SYN字段置为1,表示需要建立TCP连接。
  2. 服务端会回复客户端发送的TCP连接请求报文,其中包含seq序列号,是由回复端随机生成的,并且将回复报文的SYN字段置1,而且会产生ACK字段,ACK字段数值是在客户端发过来的seq序列号基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP建立请求已得到了验证。
  3. 客户端收到服务端发送的TCP建立验证请求后,会使自己的序列号加1表示,并且再次回复ACK验证请求,在服务端发送过来的seq基础上加1,进行回复。

建立过程状态机转变:

  1. 一开始建立连接之前服务端和客户端的状态都为CLOSED
  2. 服务端创建socket后开始监听,变为LISTEN状态。
  3. 客户端建立请求连接,向服务端发送SYN报文,客户端的状态变为SYN_SENT
  4. 服务端收到客户端的报文后会向客户端发送ACK和SYN报文,此时服务端的状态变为SYN_RCVD
  5. 然后,客户端收到ACK和SYN,会向服务器发送ACK,客户端状态变为ESTABLISHED,服务端收到客户端的ACK 后也变为ESTABLISHED
  6. 至此,TCP3次握手完成,建立连接!

这里写图片描述

断开过程:

  1. 服务端发送断开TCP连接请求的报文,其中报文中包含seq序列号,是由发送端随机生成的,并且还将报文中FIN字段置为1,表示需要断开TCP连接。
  2. 客户端会回复服务端发送的TCP断开请求报文,其中包含seq序列号,是由回复端随机生成的,而且会产生ACK字段,ACK字段数值,是在服务端发过来的seq序列号基础上加1进行回复,以便服务端收到信息时,知晓自己的TCP断开请求已得到了验证。
  3. 客户端在回复完服务端的TCP断开请求后,不会马上就进行TCP 连接的断开,客户端会先确保断开前,所有传输到服务端的数据是否已经传输完毕,一旦确认传输数据完毕就会将回复报文的FIN字段置1,并产生随机seq序列号。
  4. 服务端收到客户端的TCP断开请求后,会回复客户端的断开请求,包含随机生成的seq字段和ACK字段,ACK字段会在客户端的TCP断开请求的seq基础上加1,从而完成客户端请求的验证回复。
  5. 至此TCP断开的4次挥手过程完毕!

断开过程状态机转变:

由于TCP连接是全双工的,断开连接会比建立连接麻烦一点点。
1. 服务端先向客户端发送FIN报文,请求断开连接,其状态变为FIN_WAIT1
2. 客户端收到FIN后向服务端发送ACK,客户端状态变为CLOSE_WAIT
3. 服务端收到ACK后就进入FIN_WAIT2状态。此时连接已经断开了一半了。如果客户端还有数据要发送给服务端,就会继续发送。
4. 直到发完了,就发送FIN报文,此时客户端会进入LAST_ACK状态。
5. 服务端收到客户端的FIN后,会马上发送ACK给客户端,此时服务端进入TIME_WAIT状态
6. 再过了2MSL长的时间后服务端进入CLOSED状态。客户端收到服务端的ACK后也进入CLOSED状态。
7. 至此,还有一个状态没有提及: CLOSING状态。

CLOSING 状态表示:

  • 客户端发生了FIN,但没有收到服务器的ACK,却收到了服务器的FIN。这种情况发生在服务器发送的ACK丢包的时候,因为网络传输有时会有意外发生。

tcpdump抓包分析tcp三次握手和四次断开:

命令:
tcpdump port 22 -Stn -c 3

参数说明:
port:指定端口
-S:用绝对而非相对数值列出TCP关联数
-t:在每列倾倒资料上不显示时间戳记
-n:不把主机的网络地址转换成名字
-c <数据包数目>:收到指定的数据包数目后,就停止进行的操作

Flags说明:
[S]代表seq
[S.]代表seq和ack
[.]代表ack
[F]代表FIN
[P]代表有DATA数据传输
[R]代表连接重置 
[E]代表ECN-Echo(不了解)
[w]代表ECN CWR(不了解)

(1)三次握手
这里写图片描述

  • 看Flags标识:
  • 10.0.0.1 > 10.0.0.77:Flags为[SEW],这里看S即可,为SYN连接请求
  • 10.0.0.77 > 10.0.0.1:Flags为[S.E],这里看S和.即可,S代表SYN回复,.代表ack
  • 10.0.0.1 > 10.0.0.77:Flags为[.],即为ack确认,此时TCP三次握手建立成功

(2)四次断开

由于断开过程中会有数据传输,故在tcpdump -c指定抓包次数的时候值给大点,不然抓不到FIN断开的包。

这里写图片描述

  • 看Flags标识:
  • 10.0.0.77 > 10.0.0.1:Flags为[F.],此为10.0.0.77向10.0.0.1发送的断开FIN请求,和ack确认
  • 10.0.0.1 > 10.0.0.77:Flags为[.],10.0.0.1先发送ack确认
  • 10.0.0.1 > 10.0.0.77:Flags为[F.],10.0.0.1发送FIN确认和ack确认
  • 10.0.0.77 > 10.0.0.1:Flags为[.],10.0.0.77发送ack确认,然后连接成功断开

猜你喜欢

转载自blog.csdn.net/Mr_rsq/article/details/81082127
今日推荐