tcp握手为什么是三次不是两次_tcp的三次握手

tcp握手为什么是三次不是两次_tcp的三次握手TCP采用三次握手的原因其实非常简单,远没有大部分博客所描述的那样云山雾绕。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

参考文章

Why do we need a 3-way handshake? Why not just 2-way

大部分网络博客的错误解读

首先需要声明的是, 百度搜索到的大部分网络博客关于这个问题的解答都是不清晰或者不准确的。 讨论这个问题的大部分博客都会引用《计算机网络》的内容:

  1. 防止已失效的连接请求又传送到服务器端,因而产生错误

不幸的是, 这种解释是不准确的, TCP 采用三次握手的原因其实非常简单, 远没有大部分博客所描述的那样云山雾绕。

这里先给出结论:

  • 为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
  • 如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认

先修知识

TCP 通信流程

TCP 的通信流程
在这里插入图片描述

上图中的每一个箭头都代表着一次 TCP数据包的发送

  • 需要注意的是, 上图中出现的 ACK = x +1 的写法很容易让人误以为数据包中的 ACK 域的数据值被填成了 y+1 。 ACK = x+1 的实际含义是:
    • TCP 包的 ACK 标志位(1 bit) 被置成了 1
    • TCP 包的确认号(acknowledgement number ) 的值为 x+1
  • 类似的, TCP 数据包中的 SYN 标志位, 也容易与序号(sequence number) 混淆, 这点需要读者注意

TCP 数据包结构图
TCP包结构图

为什么 TCP 需要握手这个操作

在解答为什么 TCP 需要三次握手, 而不是两次之前, 首先需要回答的问题是:

  • 为什么需要握手这个操作, 能不能不握手?

如果读者对比一下 UDP 的通信流程和 TCP 的通信流程, 可以发现, 在 UDP 协议中, 是没有握手这个操作的。
在这里插入图片描述

这里就引出了 TCP 与 UDP 的一个基本区别, TCP 是可靠通信协议, 而 UDP 是不可靠通信协议。

  • TCP 的可靠性含义: 接收方收到的数据是完整, 有序, 无差错的。
  • UDP 不可靠性含义: 接收方接收到的数据可能存在部分丢失, 顺序也不一定能保证。

UDP 和 TCP 协议都是基于同样的互联网基础设施, 且都基于 IP 协议实现, 互联网基础设施中对于数据包的发送过程是会发生丢包现象的, 为什么 TCP 就可以实现可靠传输, 而 UDP 不行?

TCP 协议为了实现可靠传输, 通信双方需要判断自己已经发送的数据包是否都被接收方收到, 如果没收到, 就需要重发。 为了实现这个需求, 很自然地就会引出序号(sequence number)确认号(acknowledgement number) 的使用。

发送方在发送数据包(假设大小为 10 byte)时, 同时送上一个序号( 假设为 500),那么接收方收到这个数据包以后, 就可以回复一个确认号(510 = 500 + 10) 告诉发送方 “我已经收到了你的数据包, 你可以发送下一个数据包, 序号从 510 开始” 。

这样发送方就可以知道哪些数据被接收到,哪些数据没被接收到, 需要重发。

为什么需要三次握手,而非两次

正如上文所描述的,为了实现可靠传输,发送方和接收方始终需要同步( SYNchronize )序号。 需要注意的是, 序号并不是从 0 开始的, 而是由发送方随机选择的初始序列号 ( Initial Sequence Number, ISN )开始 。 由于 TCP 是一个双向通信协议, 通信双方都有能力发送信息, 并接收响应。 因此, 通信双方都需要随机产生一个初始的序列号, 并且把这个起始值告诉对方。

于是, 这个过程就变成了下面这样。
在这里插入图片描述

下面这个流程图描述的和上面一样, 但是更加清楚的展示了 TCP 数据包标志位, 以及数据域的命名来源。

Alice Bob SYN =1 , seq = x SYNchronize with my Initial Sequence Number of x SYN =1, ACK = 1, seq = y , ack = x+1 I received your ISN, I ACKnowledge that I am ready for [x+1] SYNchronize with my Initial Sequence Number of y ACK =1 , seq = x+1, ack = y+1 I received your syn, I ACKnowledge that I am ready for [y+1] Alice Bob

题外话

有一位读者关注到了三次握手中, 序列号变化的问题, 让笔者临时想起了曾经困扰自己的一个问题

  • 为什么三次握手最后一次握手中, 在上面的示意图中回复的 seq = x+1 。

答案: (此处感谢 “楚天千里清秋” 的提醒, 进行了修正)

acknowledgement number 的作用是向对方表示,我期待收到的下一个序号。 如果你向对方回复了 ack = 31, 代表着你已经收到了序号截止到30的数据,期待的下一个数据起点是 31 。

TCP 协议规定SYN报文虽然不携带数据, 但是也要消耗1个序列号, 所以前两次握手客户端和服务端都需要向对方回复 x+1 或 y+1 。

在这里插入图片描述
在这里插入图片描述
值得注意的是, 如上图所说, 最后一次握手在默认不携带数据的情况下, 由于SYN 不是 1 , 是不消耗序列号的。 所以三次握手结束后, 客户端下一个发送的报文中 seq 依旧是 x+1, 示意图如下

在这里插入图片描述
注意到, 上图第四步发送的 seq 和第三次握手的 seq 是一样的, 体现了最后一次握手, 默认不消耗序列号的特点。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/188074.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 新手小白学JAVA 正则表达式 包装类 自动装箱/自动拆箱 BigDecimal

    新手小白学JAVA 正则表达式 包装类 自动装箱/自动拆箱 BigDecimal1正则表达式Regex1.1概述正确的字符串格式规则。常用来判断用户输入的内容是否符合格式的要求,注意是严格区分大小写的。1.2常见语法1.3String提供了支持正则表达式的方法Matches(正则):当前字符串能否匹配正则表达式replaceAll(正则,子串):替换子串split(正则):拆分字符串1.4练习:测试输入身份证号创建包:cn.tedu.api创建类:TestRegex.javapackagecn.tedu.api;impo

    2022年5月2日
    39
  • GoogLeNet v1结构「建议收藏」

    GoogLeNet v1结构「建议收藏」GooLeNetInception块GooLeNetGooLeNet是google2014年推出的深度神经网络模型,原论文名称为:Goingdeeperwithconvolutions,在沐神的书上也被叫做含并⾏连结的⽹络(主要由于Inception块中的结构)。该模型在2014年ILSVRC2014比赛中竞赛中夺得冠军,14年之后也在不断发展,这里就介绍一下初始的版本。Inception块GooLeNet思想有点类似于VGG,先构建块,网络主要通过块的堆叠实现,不过这里的块与VGG块不同,称

    2022年8月14日
    10
  • yuicompressor java_YUI Compressor[通俗易懂]

    yuicompressor java_YUI Compressor[通俗易懂]简介根据雅虎卓越性能团队的说法,40%到60%的雅虎用户拥有空闲缓存体验,所有页面浏览量中约有20%是使用空缓存完成的(请参阅TenniTheurer在YUIBlog上的这篇文章)有关浏览器缓存使用的更多信息)。这一事实概述了保持网页尽可能轻量化的重要性。改进页面或Web应用程序的工程设计通常会带来最大的节省,而且应始终是主要策略。通过正确的设计,有许多提高性能的辅助策略,例如缩小代码,HTTP…

    2022年7月18日
    13
  • python tkinter窗口美化_jquery进度条插件

    python tkinter窗口美化_jquery进度条插件前言在我们进行自动化测试的时候,用例往往是成百上千,执行的时间是几十分钟或者是小时级别。有时,我们在调试那么多用例的时候,不知道执行到什么程度了,而pytest-sugar插件能很好解决我们的痛点。

    2022年7月29日
    8
  • Binwalk工具的详细使用说明

    https://blog.csdn.net/QQ1084283172/article/details/66971242一、binwalk工具的基本用法介绍1.获取帮助信息$binwalk-h#或者$binwalk–help2.固件分析扫描$binwalkfirmware.bin#或者$binwalkfirmware.bin|hea…

    2022年4月4日
    38
  • 淘宝客系统教学系列_1.简单介绍和平台搭建

    淘宝客系统教学系列_1.简单介绍和平台搭建转载http://www.grcloud.cn/?p=1532013年2月15日各位好.我们是工尔科技工作室.长年从事php等web程序开发和二次开发的承接.近几年追着网络购物越来越流行.一些周边服务也犹如春笋.这次要讲的就是pinphp.一个购物分享的开源系统…

    2022年6月6日
    36

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号