(学习笔记-TCP连接建立)TCP 为什么是三次握手?不是两次、四次?

常规回答:“因为三次握手才能保证双方具有接收和发送的能力”


原因一:避免历史连接

三次握手的首要原因是为了防止旧的重复连接初始化造成混乱

假设:客户端先发送了SYN(seq=90)报文,然后客户端宕机了,而且这个SYN报文还被网络阻塞了,服务端并没有收到,接着客户端重启后,又重新向服务端建立连接,发送了SYN(seq=100)报文。(这里不是重传,而是重新发送请求)

三次握手避免历史连接

 客户端连续发送多次SYN(都是同一个四元组)建立连接的报文,在网络拥堵的情况下:

  • 一个[旧的SYN报文]比[最新的SYN]报文早到达了服务端,那么此时服务端就回一个SYN+ACK报文给客户端,此报文中的确认号是91(90+1)
  • 客户端收到后,发现自己期望收到的确认号应该是100+1,而不是90+1,于是就会回RST报文
  • 服务端收到RST报文后,就会释放连接。
  • 后续最新的SYN抵达了服务端,客户端与服务端就可以正常的完成三次握手了。

上述中的「旧 SYN 报文」称为历史连接,TCP 使用三次握手建立连接的最主要原因就是防止「历史连接」初始化了连接

 TIP

如果服务端在收到 RST 报文之前,先收到了「新 SYN 报文」,也就是服务端收到客户端报文的顺序是:「旧 SYN 报文」->「新 SYN 报文」,此时会发生什么?

当服务端第一次收到 SYN 报文,也就是收到 「旧 SYN 报文」时,就会回复 SYN + ACK 报文给客户端,此报文中的确认号是 91(90+1)。

然后这时再收到「新 SYN 报文」时,就会回 Challenge Ack (opens new window)报文给客户端,这个 ack 报文并不是确认收到「新 SYN 报文」的,而是上一次的 ack 确认号,也就是91(90+1)。所以客户端收到此 ACK 报文时,发现自己期望收到的确认号应该是 101,而不是 91,于是就会回 RST 报文。

如果是两次握手连接,就无法阻止历史连接,那为什么TCP两次握手就无法阻止历史连接呢?

因为在两次握手的情况下,服务端没有中间状态给客户端来阻止历史连接,导致服务端可能建立一个历史连接,造成资源浪费。

在两次握手的情况下,服务端在收到 SYN 报文后,就进入 ESTABLISHED 状态,意味着这时可以给对方发送数据,但是客户端此时还没有进入 ESTABLISHED 状态,假设这次是历史连接,客户端判断到此次连接为历史连接,那么就会回 RST 报文来断开连接,而两次握手而服务端在第一次握手的时候就进入 ESTABLISHED 状态,所以它可以发送数据的,但是它并不知道这个是历史连接,它只有在收到 RST 报文后,才会断开连接。

 可以看到,如果采用两次握手建立 TCP 连接的场景下,服务端在向客户端发送数据前,并没有阻止掉历史连接,导致服务端建立了一个历史连接,又白白发送了数据,妥妥地浪费了服务端的资源。

因此,要解决这种现象,最好就是在服务端发送数据前,也就是在建立连接前,要阻止掉历史连接,这样就不会造成资源浪费,所以需要三次握手。

所以TCP使用三次握手建立连接的最主要原因是防止[历史连接]初始化了连接


原因二:同步双方初始序列号

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

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

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

四次握手其实也能够可靠的同步双方的初始化序号,但由于第二步和第三步可以优化成一步,所以就成了[三次握手]。

 两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。


原因三:避免资源浪费

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

如果客户端发送的SYN报文在网络中阻塞了,重复发送多次SNY报文,那么服务端在收到请求后就会建立多个冗余的无效链接,造成资源浪费。(因为两次握手的情况下,服务端在接收到SYN报文后就会建立连接)

这里两次握手是假设「由于没有第三次握手,服务端不清楚客户端是否收到了自己发送的建立连接的 ACK 确认报文,所以每收到一个 SYN 就只能先主动建立一个连接」这个场景。


结论

TCP建立连接时,通过三次握手能够防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。

不使用两次握手和四次握手的原因:

  • 两次握手:无法防止历史连接的建立,会造成双方资源的浪费,无法可靠的同步双方序列号
  • 四次握手:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Telnet是一种用于文本方式远程管理计算机或路由器等网络设备的协议,它使用TCP的端口号23进行通信。三次握手TCP连接建立过程。在telnet连接中,当客户端主动打开连接并结束CLOSED阶段时,服务器端也结束CLOSED阶段,然后开始进行三次握手。 具体来说,当客户端发送一个连接请求报文段时,服务器端收到请求后会发送一个确认报文段作为响应。这个确认报文段中会包含一个随机生成的序列号,用于客户端确认连接建立。接着,客户端会发送一个连接确认报文段,服务器端收到后确认连接成功建立,然后可以开始进行telnet会话。 总结起来,telnet的三次握手过程是客户端通过发送连接请求,服务器端通过发送确认响应,最后客户端再发送连接确认来建立连接。这个过程确保了客户端和服务器端之间的可靠通信。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [HCIA 网络基础(3)](https://blog.csdn.net/weixin_43947756/article/details/108639182)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [应用层TCP三次握手及各种协议简介telnet【笔记】](https://blog.csdn.net/weixin_34246551/article/details/92523030)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值