news 2026/5/15 16:16:05

TCP专栏-3.三次握手

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TCP专栏-3.三次握手

什么是三次握手

三次握手是指,在建立TCP连接时,客户端和服务端总共会发送三个数据包。只有三个数据包都发送成功后,TCP连接才会建立成功。否则,丢失任何一个包,都会导致连接建立失败。发送三个数据包的过程,被人形象的称为三次握手。

三次握手过程

如图,是我找到的三次握手示意图:

通常,在socket编程中,服务端会绑定端口,然后调用listen接口,挂起等待。而客户端会绑定服务端的IP和端口,然后调用connect接口,发起连接。连接成功后,双方便会相互发送消息。其实,这个过程就是TCP建立连接的过程,也就是三次握手过程。只是底层原理和过程全部封装在内核层面上,用户编程时无需感知和亲自操作。

那现在就详细说下这个建立连接的过程。首先第一次握手时,客户端会发送一个报文,其中标志位SYN=1,其余为0。表示这是一个请求建立连接的报文。同时客户端还会生成一个随机数x,当作序列号,即seq=x,也称之为初始序列号。后续的序号确认、超时重传、重复丢弃等等,都会基于这个初始序列号去做。所以这个初始序列号很关键。前面我们知道,序列号seq占4个字节,所以x的范围也就是[0,4294967295]。

服务端收到这个报文后,通过SYN=1便可以知道,这是一个请求建立连接的报文。如果此时,服务端已经准备好,同意建立连接。那么它便会回复一个确认报文,即ACK=1,ack=x+1。注意,普通报文中ACK为0,确认报文中ACK一定为1。那ack为啥是x+1呢?

首先我们要明白,大写的ACK是标志位,小写的ack是确认号。确认号就是用来回复对方的,告诉对方,我接收了多少数据,下次你应该从哪里发送(参考上一章节)。那为啥是x+1,而不是x+100或+1000呢?这里就要说下ack的计算逻辑了。如果发送方发送的序号是x,携带数据长度是n。如果接收方全部接收成功,则返回的ack就是x+n。这样我们只需要知道建立连接时,携带数据长度是多少就行了。答案是,三次握手中,三个包均没有携带任何数据,即数据长度为0。那为啥不是x+0呢?答案是,TCP协议约定,SYN=1的报文段不能携带数据,但要消耗掉一个序号。FIN报文同样如此,即使不携带数据,也要消耗一个序号。所以,确认号就是x+1,即ack=x+1。

tcp是全双工的,就是双方都能收发数据。那客户端到服务端的连接通了后,服务端肯定也要向客户端发起请求,建立连接。过程和客户端发起时一模一样,就是发送一个报文,其中SYN=1,序号seq=y。聪明的你,立马会想到,到这里,服务端已经发送了两个报文,一个是确认报文ACK=1,一个是请求建立连接报文SYN=1。这和上面只发送一条报文,显然是不一样的。为什么呢?答案是,TCP协议做了优化,将两条报文合并成一个报文了。就是服务端只发送一条报文:SYN=1,SCK=1,seq=y,ack=x+1,既表示确认报文,又表示请求建立连接报文。这在TCP中被称为“捎带应答”。这个全部过程也被称为二次握手。(这里,也说明为啥建立连接时候,最少需要3次握手,其实4次更标准,但效率低,没必要。)

客户端收到服务端的SYN=1报文后,立即回复一个确认报文:ACK=1,seq=x+1,ack=y+1。此时的确认号ack的计算逻辑和上面一样,所以是y+1。这个过程被称为第三次握手。

下面,我同时用抓包的报文数据来验证这个过程。图如下:

前三行,就是三次握手中的三个包。第一次握手,客户端->服务端:SYN=1,seq=0。第二次握手,服务端->客户端:SYN=1,ACK=1,seq=0,ack=1。第三次握手,客户端->服务端:ACK=1,seq=1,ack=1。注意,此处的两个初始序列号都是0,这里的0是相对值,只是展示方便。实际传输的都是真实值,一般比较大。后面讲解抓包的报文时,再详细说明。

三次握手结束后,连接正式建立成功,双方便可以相互发送数据了。

三次握手中同步哪些信息

上面示意图简化了建立连接的过程。从上面我们知道,建立TCP连接时候,双方会互相同步自己的初始序列号,后续的确认号都是基于这个而来。那除了这个外,还同步哪些信息呢?从上面抓包的报文中还可以看到,有win,MSS,SACK_PERM,以及时间戳等。

其中,win表示窗口大小,后面每个报文中也都会携带上,用来告知对方,我的剩余缓冲区空间还有多大,你下次还能发多少。这个不是只在建立连接时候才有,每次收发报文都会带上,故先忽略。

而MSS和SACK这两个,是明确只在建立连接时候才有,其余报文中不会携带。上一章节说过,MSS的出现是为了解决TCP包过大而导致被分片。而MSS又依赖网卡的MTU,MTU越大,单包携带的有效数据便越多。那如果双方机器性能不一样,怎么办呢?举例,如果客户端MTU=2000,服务端MTU=1500。TCP/IP包头都是按最小情况算(下同),在不交换信息情况下,客户端的MSS最大便可以达到2000-20-20=1960,而服务端的MSS最大是1500-20-20=1460。

如果此时客户端发送TCP包携带数据长度是1800字节(不超过1960,正常数据包),则到达网络层后,IP包大小为1800+20+20=1920字节。虽然1920<2000,在客户端网络上不会被分片,但到达服务端时,还是会因为超过了1500,在服务端上被分片。依旧会造成丢包等问题。

所以TCP建立连接时,需要协商一个双方都支持的最小MSS,也就是取客户端和服务端两个中最小的那个MSS。这也是为啥必须在建立连接时候同步MSS的原因。MSS一旦确定后,不在改变,所有后续包不会再携带这个信息。

同理,SACK也是这个原因,才会出现在首次建立连接中。只有双方都支持SACK才行。仔细点会发现,连接建立时候发送的是SACK_PERM,全称是SACK-Permitted。表示是否允许开启SACK这个选项功能,不允许就算了,允许后,后续报文头的选项中,可能会出现SACK的内容。就是批量发送报文中,哪些区间丢失了,在SACK中体现。后面只需要针对性重传这些丢失的区间就行,不用全部都传输,提高了效率。

所以,让我们总结下,三次握手时会同步哪些信息:初始序列号、MSS、SACK、时间戳等

为什么不能两次握手

首先,从理论上分析,为啥不能两次握手就可以建立连接。

TCP传输是可靠的,是全双工的。双方都需要知道自己的发送和接收是否正常。如果是两次握手,即A发送信息给B,B接收到后返回消息给A。到这里,A是能够确认自己的发送和接收是没问题的,但B只能确认自己的接收没有问题,无法确认自己的发送是否正常。只有A给B回消息后,B收到了,才能确认自己的发送也没问题。所以,从理论上讲,要想确认双方收发是否都正常,两次报文交互是做不到的,至少三次。

另外,也可以从实现上面来分析下,两次握手会有哪些危害。先说结论,两次握手会导致两个问题:

1.造成服务端资源浪费、产生大量无效连接。

2.影响新的连接,可能会引起脏数据或中断当前新连接。

是想下,如果两次握手即可成功建立连接。那么如果某一次的SYN报文超时了,那客户端会重新发送一次SYN报文,服务端正常接收后建立连接。但过了一会,刚才超时的SYN报文又到达服务端了,服务端又会创建一个连接。这样一来,就产生了两个连接。如果多个客户端多次超时后,就会产生很多个无效连接。服务端创建连接的本质,就是分配缓存,占用端口资源。这样就造成了服务端资源浪费。

那为什么三次握手不会有这种情况呢。同样的过程,超时SYN重新到达服务端后,服务端还是会分配缓存,占用端口。但此时服务端给客户端回复消息后,客户端判断连接已经建立成功了。这次的SYN,不是新的,而是旧报文延迟了,直接丢掉就行。客户端便会返回一个RST给客户端,告诉对方,把刚才创建的多余缓存都释放了吧。这样,就不存在资源浪费了。

至于第二种情况,产生的原因则更为复杂。如果旧连接断开后,客户端又立马发起一次新的连接。且端口被快速复用,双方四元组和之前一模一样。那么,如果此时有一个滞留很久的旧包过来了,接收方如何处理呢?

1.如果旧包的序列号或会话等信息,完全超出新连接的窗口范围,接收方便认定这个包不属于当前连接。是一个旧的非法数据,它会直接丢弃这个数据,并立刻发送RST给对方。刚建立的正常新连接,直接被强制断开。

2.果旧包的序列号或会话等信息,在新连接的窗口范围。内核会认为这个包是正常的,不丢弃,按正常数据处理。此时,读取出来的数据就是脏数据。

建立连接时出现问题怎么办

重传机制是怎样的

如何判断是同一个链接

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/15 16:13:48

PPTAgent终极指南:如何用AI在5分钟内创建专业演示文稿

PPTAgent终极指南&#xff1a;如何用AI在5分钟内创建专业演示文稿 【免费下载链接】PPTAgent An Agentic Framework for Reflective PowerPoint Generation 项目地址: https://gitcode.com/gh_mirrors/pp/PPTAgent PPTAgent是一个创新的AI演示文稿生成框架&#xff0c;能…

作者头像 李华
网站建设 2026/5/15 16:11:11

终极指南:3分钟掌握IDM激活脚本完整使用方法

终极指南&#xff1a;3分钟掌握IDM激活脚本完整使用方法 【免费下载链接】IDM-Activation-Script-ZH IDM激活脚本汉化版 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script-ZH 还在为Internet Download Manager&#xff08;IDM&#xff09;的30天试用…

作者头像 李华
网站建设 2026/5/15 16:10:03

免费AI文生视频平台(长视频)-更新

先附上网站地址:www.pyaitool.cn 备用网址:http://pyaitool.cn:8081 完全免费&#xff0c;完全免费。登录密码:admin 更新了界面和功能&#xff0c;夏天到了&#xff0c;就来点夏日元素&#xff0c;界面AI改的&#xff0c;后端AI做的&#xff0c;前端AI做的。属于是提示词工程。…

作者头像 李华
网站建设 2026/5/15 16:06:33

从引脚到协议:Microchip SAM D51与LAN9253 EtherCAT从站硬件设计全解析

1. 芯片选型与核心架构解析 第一次接触工业以太网从站设计时&#xff0c;面对琳琅满目的芯片型号确实容易犯选择困难症。经过多个项目的实战验证&#xff0c;我发现Microchip SAM D51与LAN9253的组合堪称黄金搭档。SAM D51作为Cortex-M4F内核的MCU&#xff0c;主频120MHz的性能…

作者头像 李华
网站建设 2026/5/15 16:05:04

AB下载管理器终极指南:3步掌握高效文件下载的完整方法

AB下载管理器终极指南&#xff1a;3步掌握高效文件下载的完整方法 【免费下载链接】ab-download-manager A Download Manager that speeds up your downloads 项目地址: https://gitcode.com/GitHub_Trending/ab/ab-download-manager 你是否厌倦了浏览器下载的缓慢速度&…

作者头像 李华
网站建设 2026/5/15 16:03:45

别再只刷Demo了!手把手教你用CCS给AWR1843毫米波雷达写自己的‘大脑’

从Demo玩家到雷达开发者&#xff1a;AWR1843毫米波雷达CCS深度开发实战 毫米波雷达技术正在智能驾驶、工业检测等领域掀起革命浪潮。作为TI明星产品&#xff0c;AWR1843凭借其高性价比和丰富功能成为众多开发者的首选。但大多数用户止步于运行官方Demo&#xff0c;未能真正释放…

作者头像 李华