当前位置: 首页 > article >正文

TCP连接为什么是三次握手,而不是两次和四次

答案

  • 阻止重复的历史连接
  • 同步初始序列号
  • 避免资源浪费

原因

阻止重复的历史连接(首要原因)

考虑这样一种情况:


客户端现在要给服务端建立连接,向服务端发送了一个SYN报文段(第一次握手),以表示请求服务端连接,但是该SYN报文段由于网络拥塞原因阻塞在了网络中迟迟没有到达服务端,故而在触发超时重传机制后,客户端又发生了一个新的SYN报文段给服务端以表示请求连接。

假如过了一段时间之后,旧的SYN报文段与新的SYN报文段都到达了服务端,此时服务端该如何区分新旧报文段,又或者说服务端该如何拒绝旧的SYN报文段而只响应新的SYN报文段呢(因为对新的连接请求进行响应才是客户端需要的,但是服务端该如何拒绝旧的响应)

接下来我们来针对这种情况进行分析,来说明三次握手为什么可以拒绝旧的历史请求(也就是上述所说的,旧的SYN报文段)

第一种情况

超时后client收到了旧的SYN报文段响应,但是新的SYN报文段已经发送了,此时client收到旧的SYN报文段响应,发现与期望的不对应(client期望收到新的SYN报文段ack,而不是旧的ack),于是向server发生一个RST报文段,目的是告诉server旧的SYN报文是错的,让server释放掉它

第二种情况

超时后,新旧SYN报文段都到达了server端,且client端并未收到server端的回复

此时由于第三次握手的存在,server端并不立即分配资源,而是发现新旧两个SYN报文段的seq序号是失序的(旧的seq是90,而新的seq是100),由于tcp在面对失序报文段情况下,只对连续收到的最新序号进行回应,因此server端将回复client一个序号为91的ack,同样client端收到这个ack序号时发现跟自己期望的不一样(期望的是101),于是给server发送一个RST,让server释放掉序号为91的SYN报文段。

由上可见,正是由于第三次握手的存在,使得sever端在收到旧的历史连接之后,得以不立即分配资源,且可以等待client的回复以发现这是一个旧的SYN,从而拒绝掉它。

反过来,假如只有两次握手,那么server端将无法得知client发送过来的两次连接请求到底哪一个才是client需要的。

同步初始序列号

TCP 协议的通信双方, 都必须维护一个「序列号」, 序列号是可靠传输的一个关键因素,它的作用:

  • 接收方可以去除重复的数据
  • 接收方可以根据数据包的序列号按序接收
  • 可以标识发送出去的数据包中, 哪些是已经被对方收到的(通过 ACK 报文中的序列号知道);

可见,序列号在 TCP 连接中占据着非常重要的作用,所以当客户端发送携带「初始序列号」的 SYN 报文的时候,需要服务端回一个 ACK 应答报文,表示客户端的 SYN 报文已被服务端成功接收,那当服务端发送「初始序列号」给客户端的时候,依然也要得到客户端的应答回应这样一来一回,才能确保双方的初始序列号能被可靠的同步。

避免资源浪费

如果只有两次握手,当客户端发生的 SYN 报文在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN ,由于没有第三次握手,服务端不清楚客户端是否收到了自己回复的 ACK 报文,所以服务端每收到一个 SYN 就只能先主动建立一个连接,这会造成什么情况呢?

如果客户端发送的 SYN 报文在网络中阻塞了,重复发送多次 SYN 报文,那么服务端在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。

为什么不是四次握手

上述提到,三次握手可以同步双方的初始序号,其实四次握手也可以,但是在四次握手的过程可以完全优化为三次握手,如下图所示,因此就成了三次握手

参考:

4.1 TCP 三次握手与四次挥手面试题 | 小林coding (xiaolincoding.com)


http://www.kler.cn/a/160145.html

相关文章:

  • 如何在Mac上切换到JDK 17开发环境
  • 玩转ChatGPT:文献阅读 v2.0
  • Unity安装后点击登录没反应
  • Android 13 实现屏幕熄屏一段时候后关闭 Wi-Fi 和清空多任务列表
  • Ps:OpenColorIO 设置
  • Iotop使用
  • rabbitmq技术
  • 浅析计算机网络安全的的防范与措施
  • java开发中Dao层和Mapper层的关系
  • 微信玩具小程序商城开发技巧
  • 网络安全威胁——跨站脚本攻击
  • 【tower-boot 系列】redis集成
  • docker安装及配置mysql
  • HarmonyOS 修改App的默认加载的界面(ArkTS版本)(十七)
  • [Electron] 将应用打包成供Ubuntu、Debian平台下安装的deb包
  • DAPP开发【11】IPFS星际文件管理系统
  • spark的安装与使用:一键自动安装
  • TCP与UDP的区别
  • HashMap系列-放入元素的流程
  • 面试官问:怎么判断对象已死?
  • 近期复习四
  • 《微信小程序开发从入门到实战》学习四十二
  • 不同数据库进行同步和增量数据(SQL server 与MySQL数据库为例)
  • Ubuntu防止休眠和挂起(笔记)
  • HTML总结
  • Image Segmentation Using Deep Learning: A Survey