前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >tcp为什么是三次握手

tcp为什么是三次握手

作者头像
平凡的学生族
发布2019-06-11 14:34:44
1.1K0
发布2019-06-11 14:34:44
举报
文章被收录于专栏:后端技术后端技术

参考

TCP 为什么是三次握手,而不是两次或四次?

1. tcp三次握手流程

image.png

由图可知,tcp三次握手的关键在于,序列号seq的交换确认。

2. 为什么不能是两次握手

因为对于客户端和服务端来说,双方对对方的序列号的确认是可靠传输的关键。 两次握手的过程如下:

  1. A 发送同步信号SYN + A's Initial sequence number
  2. B 发送同步信号SYN + B's Initial sequence number + B's ACK sequence number

当第二步的动作完成时,我们可以保证B已知晓A的序列号,因为第二步只有在第一步成功后才执行。但不能保证A知晓B的序列号,因为第二步的传输可能失败。

图中省略了这两次握手中,发送了SYN=1的细节

两次握手完成后,由于我们假设了,tcp只有二次握手,那么二次握手完成时,B就得自认为连接已经建立,不管第二次握手的传输是否成功。 那么,假如第二次握手的传输失败了,A就不会收到B的序列号,也就无法确定B的数据传输起始于第几号。 这时,B向A发送了一些数据(TCP是全双工通信,所以服务端B可以主动向客户端A发信息),并附上了序列号20000,被A收到:

此时A就面临着两个尴尬的选择:

  1. A可以保持数据包。但是A连B的起始序列号都不知道,这个数据包要保存到什么时候,才能回复ACK呢?
  2. A可以回复ACK。ACK的含义表示它的序号之前的字节数据都已收到,可是A连B的起始序列号都不知道:起始序列号可能是100,也可以是1000,A根本无法确定还缺哪些序号的字节,也就更不敢回复ACK了。

所以,不管哪个选择,都是不妥当的。这正是因为A没有确认B的序列号。 而在tcp中,通过三次握手,和丢包的处理机制,A和B都会确定自己的序列号被对方接收。

3. tcp对三次握手中丢包的处理

照搬自TCP 为什么是三次握手,而不是两次或四次? tcp除了采用三次握手,还要对丢包意外进行适当的处置,以保证A、B双方序列号的传输和确认。

  1. 如果第一个包,即A发给B的SYN 中途被丢,没有到达B A会周期性超时重传,直到收到B的确认
  2. 如果第二个包,即B发给A的SYN +ACK 中途被丢,没有到达A B会周期性超时重传,直到收到A的确认
  3. 如果第三个包,即A发给B的ACK 中途被丢,没有到达B A发完ACK,单方面认为TCP为 Established状态,而B显然认为TCP为Active状态: a. 假定此时双方都没有数据发送,B会周期性超时重传,直到收到A的确认,收到之后B的TCP 连接 也为 Established状态,双向可以发包。 b. 假定此时A有数据发送,B收到A的 Data + ACK,自然会切换为established 状态,并接受A的 Data(发ACK的同时顺便把Data带上)。 c. 假定B有数据发送,数据发送不了,会一直周期性超时重传SYN + ACK,直到收到A的确认才可以发送数据(没收到A的确认,连接就还没建立,就不能传输数据)。

这样,tcp的三次握手,加上对丢包的处理机制,就保证了A、B对双方序列号的确认。也就建立了可靠传输的基础。

4. 为什么不能是四次握手

把四次握手中的第二和第三步合并起来,就是三次握手了。为了提高效率,是可以合并第2、3步的。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.06.04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考
  • 1. tcp三次握手流程
  • 2. 为什么不能是两次握手
  • 3. tcp对三次握手中丢包的处理
  • 4. 为什么不能是四次握手
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档