电子产业一站式赋能平台

PCB联盟网

搜索
查看: 69|回复: 0
收起左侧

为什么TCP需要3次握手而不是2次?

[复制链接]

344

主题

344

帖子

3148

积分

四级会员

Rank: 4

积分
3148
发表于 2024-11-9 11:45:00 | 显示全部楼层 |阅读模式
关注+星标公众,不错过精彩内容

dmh4wtbwvdx640119516143.gif

dmh4wtbwvdx640119516143.gif

来源 | 码农的荒岛求生

今天来聊聊为什么TCP需要3次握手而不是2次。假设有一条河,河的上下游有两个人,这两个人只能借助这条河交流信息:

x0cgi0jlnwu640119516243.png

x0cgi0jlnwu640119516243.png

岸边有很多叶子,因此它们把信息写到岸边的叶子上:

3amofxdfgat640119516343.png

3amofxdfgat640119516343.png

并假设上游的叶子会飘向下游,下游的叶子会飘向上游。

0t52loecmuo640119516443.png

0t52loecmuo640119516443.png

但由于水流的作用,同一个方向叶子先出发的有可能后到(乱序),也有可能沉到水里(丢失)。也就是说假如a发了四片叶子,每片叶子上写两个字,记录的是“码农的荒岛求生”,a依次把【码农】【的荒】【岛求】【生】放到河里,这四片叶子到达b后可能变成了【岛求】【码农】 【生】 【的荒】(乱序),也有可能丢了一片叶子,变成了【的荒】 【码农】 【生】(乱序+数据丢失):

emtfy0r4gea640119516543.png

emtfy0r4gea640119516543.png

那么在这种情况下该怎么让b知道a想说的其实是“码农的荒岛求生”呢?很简单,只要两种机制:编号以及确认。编号针对与乱序问题,确认机制针对的是丢失问题。a放到河里的任意一片叶子都带上一个编号,这些编号依次递增,b收到叶子后根据编号重组起来,这样即使叶子到达的顺序是乱的b也能根据编号恢复信息:

uwgoajga3s0640119516644.png

uwgoajga3s0640119516644.png

乱序问题解决了,叶子丢失问题依靠确认机制:b收到每一片叶子后会回复一个收到,并附带接收叶子的编号+1,也就是期待a发出的下一片叶子的编号:

uvbv2lpf2ch640119516744.png

uvbv2lpf2ch640119516744.png

这样a在接收到【3 收到】后就确信b已经收到了【2 的荒】,如果a在一定时间内没有收到【3 收到】那么就会重新拿起一片叶子再次发送【2 的荒】。

mmqwf13k5f3640119516844.png

mmqwf13k5f3640119516844.png

可以看到利用这种重传机制确保即使叶子可能沉到水里也能把信息发给b。有了编号和确认机制,即使在河流这种不可靠的介质中a也可以把信息可靠的传递给b。当然b也可以利用这种机制把消息可靠的发送给a。由于需要对每片叶子进行编号,因此a向b发送消息之前必须把叶子的初始编号告诉b,又因为b也可以向a发送消息,因此双方在通信之前必须知道对方叶子的初始编号,这样才能正确的进行叶子收到后的确认以及对叶子根据编号进行重排。

4yqe1clcq40640119516944.png

4yqe1clcq40640119516944.png

于是ab双方协定,聊天发起方先把编号告诉聊天接收方,聊天接收方收到发起方编号后也把自己的编号告诉发起方。依然假设a先发起通信,a先发送了一片叶子,写着“SYN X”,SYN表示这是一片告诉你我的初始编号的叶子(在TCP中SYN是synchronization的简写,表示同步,但作用和这里一样),X表示自己的初始编号。

3np11gazyri640119517044.png

3np11gazyri640119517044.png

根据之前提到的确认机制,b在收到需要对这片叶子进行确认,于是b发送一片叶子:“ACK X+1”,表示“我确认已经接收到了你的叶子,期待接收X+1号叶子”(在TCP中ACK是acknowledge的简写,表示确认,作用和这里一样)。

l3rkgijtazi640119517144.png

l3rkgijtazi640119517144.png

不要忘了,b也要把自己的编号告诉a,于是b紧接着又发送了一片叶子“SYN Y”,表示“这是一片告诉你我的初始编号的叶子,我的初始编号是Y”:

mox1uqd5vme640119517244.png

mox1uqd5vme640119517244.png

同样的a收到后也要进行确认,于是a发送一片叶子:“ACK Y+1”,表示“我确认已经接收到了你的叶子,期待接收你Y+1号叶子”。

gsdt4zaxuep640119517344.png

gsdt4zaxuep640119517344.png

就这样经过最少四片叶子,a和b就能知道对方的初始编号是多少,注意看这里:

j1lpmyj3gwm640119517445.png

j1lpmyj3gwm640119517445.png

可以看到这两片叶子都是b发向a的,因此这两片叶子的信息可以合并在一起,这样就可以少发送一片叶子:

fsy31ls35wg640119517545.png

fsy31ls35wg640119517545.png

可以看到,双方至少需要发送3片叶子才能知道对方的初始编号,而如果只发送两片叶子没办法保证这一点。------------ END ------------

fgmcijqaez1640119517645.gif

fgmcijqaez1640119517645.gif

●专栏《嵌入式工具●专栏《嵌入式开发》●专栏《Keil教程》●嵌入式专栏精选教程
关注公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。

点击“阅读原文”查看更多分享。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表