TCP三次握手和四次挥手

一. TCP概述

通过TCP/IP协议的学习,我们可以了解到--TCP是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接(三次握手),传输完毕后要断开连接(四次握手)。

二. TCP三次握手

  1. TCP头部结构
     TCP三次握手和四次挥手1 序号:Seq序号(32位),用来标识从计算机A发送到计算机B的数据包的序号,计算机发送数据时对此进行标记。
    2 确认号:Ack确认号(32位),Ack = Seq + 1
    3 标志位:每个标志位占用1Bit,分为 URG、ACK、PSH、RST、SYN、FIN,具体含义如下:
    SYN:同步序列编号,在建立连接时发送
	ACK:确认序号有效
	FIN:断开一个连接
	PSH:接收方应该尽快将报文交给应用层
	RST:重置连接
	URG:紧急指针有效
  1. 三次握手过程
     
    ① 客户端给服务端发一个 SYN 报文,并指明客户端的初始 化序列号
    ② 服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且指定了自己的初始化序列号
    ③ 客户端收到 SYN 报文之后,会发送一个 ACK 报文

过程如图:
TCP三次握手和四次挥手发送第一个SYN的一端将执行主动打开,接收这个SYN并发回下一个SYN的另一端执行被动打开。

三. TCP四次挥手

TCP 连接的拆除需要发送四个包,因此称为四次挥手。
客户端发起关闭请求,四次挥手的过程

  • 客户端发送一个 FIN 报文,报文中会指定一个序列号
  • 服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明收到客户端的报文
  • 若服务端也想断开连接,和客户端的第一次挥手相同,发送 FIN 报文
  • 客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,把服务端的序列号值 +1 作为自己 ACK 报文的序列号值

过程如图:
TCP三次握手和四次挥手

四. 实例监测

tcpdump
之前暑假写过聊天室,就用聊天室在本机来测试三次握手
因为都是在本机同时运行client和server所以命令为:
tcpdump -i lo port 4508 -S,
使用tcpdump观察如下:TCP三次握手和四次挥手从tcpdump的数据,可以明显的看到三次握手的过程是:
第一次握手
client SYN = 1, Seq = 2341371368 —> server
第二次握手
server SYN = 1,Seq = 2511815235;
ACK = 1, ack = 2341371368 + 1 —> client
第三次握手
client ACK = 1, ack = 2511815235 + 1 -->server

五. 补充问题

  1. 为什么需要三次握手?
    第一次握手:客户端发送网络包,服务端收到。
    客户端的发送、与服务端的接收正常
    第二次握手:服务端发包,客户端收到。
    服务端的接收、发送,与客户端的接收、发送正常。
    但服务器并不确认客户端的接收能力是否正常。
    第三次握手:客户端发包,服务端收到。
    服务器发送、接收能力正常。
  2. 为什么需要四次挥手?
    首先,当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。
    其次,关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。
    所以,只有等到Server端所有的报文都发送完了,client端才能发送FIN报文,因此不能一起发送。

参考以下文章
TCP三次握手详解-深入浅出(有图实例演示)
面试官,不要再问我三次握手和四次挥手
我终于搞懂了TCP的三次握手和四次挥手(图片案例超详解)

上一篇:新一代容器平台ACK Anywhere,来了


下一篇:springboot 整合使用 rabbitmq