pythonsocket中tcp通信接收不到数据_TCP 为什么三次握手而不是两次握手(正解版)...

203d6bdd57f79dd60ed5fdb65c508d15.png

先说结论

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

先修知识

TCP 通信流程

TCP 的通信流程

4cb4ceafc43023d0570dac3ace8dd4f1.png

上图中的每一个箭头都代表着一次 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 数据包结构图

6e3c90237ef4d372de149eb091f39121.png

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

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

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

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

ebf5a1b933e28db3259ac63a24882f11.png

这里就引出了 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 是一个双向通信协议, 通信双方都有能力发送信息, 并接收响应。 因此, 通信双方都需要随机产生一个初始的序列号, 并且把这个起始值告诉对方。

于是, 这个过程就变成了下面这样。

f5489eee97eba4f3b1f60a88a478bb83.png

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

62dd341f9d6a27d57e863b8ede9e522c.png

题外话

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

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

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

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

7e6b580038c5ae592f0045ba66571b9a.png

9c13b958d4e03222ae4fe9e96f82d502.png

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

50f05216dd3400e8402fb737c69956b9.png

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

原文链接:TCP 为什么三次握手而不是两次握手(正解版)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/527182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql无法启动如何备份文件_mysql 5.7 停电导致无法启动、如何备份数据,重新安装mysql...

用于记录服务器停电导致,mysql启动失败后,如何备份数据,重新安装mysql,主要分为数据备份,mysql重新安装。1、mysql无法启动时,进行数据备份。执行:systemctl start mysqld,启动失败。…

python tkinter entry默认值_Python ---(六)Tkinter窗口组件:Entry

The Tkinter Entry Widget##简介Entry(输入框)组件通常用于获取用户的输入文本。##何时使用 Entry 组件?Entry 组件仅允许用于输入一行文本,如果用于输入的字符串长度比该组件可显示空间更长,那内容将被滚动。这意味着该字符串将不能被全部看…

java 静态块初始化_简单了解java中静态初始化块的执行顺序

这篇文章主要介绍了简单了解java中静态初始化块的执行顺序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下在java中,其应该是先于所有的方法执行。下面是测试代码:public class Test1 {st…

java 常量区存放 new_java---堆、栈、常量池的存储数据

说到Java中堆、栈和常量池,首先还是看看他们各自存放的数据类型吧!栈:Java的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)也叫静态存储区。堆区:(存放所有new出来的对象;)1.存储的全部是对象&#xff0c…

log加时间 securecrt_SecureCRT配置自动记录日志

很多人用SecureCRT时,希望自动记录日志,一个是方便以后查阅,一个是对自己的操作有个记录。可以看看自己做了什么操作,有时甚至可以看看之前是不是犯了什么错,是个很不错的功能。设置很简单,还可以根据连接的…

java泛型改进_java泛型高级篇 - 真正理解协变与逆变 | 鱼儿的博客

无论你是否听过java泛型的协变与逆变,我们直接进入例子,一起来看一下java泛型比较高级的用法。例子1:copy函数第1个例子我们实现copy函数,它将List中的元素复制到List中。JavaList src Arrays.asList(1,2,3,4,5);List dst new A…

java实训遇到问题解决_「instantiationexception」关于java出现 java.lang.InstantiationException异常的分析与解决方案 - seo实验室...

instantiationexceptionjava.lang.instantiationexception 是指不能实例化某个对象,一般在我们使用java反射机制去创建某个对象的时候实例化到了一个抽象类或者接口(java中抽象类和接口是不能被实例化),而今天我遇到的则是我在使用反射机制实例化某个持久…

java对外发布接口文档_java之接口文档规范

一、xxxxxx获取指定任务爬取的所有url的接口接口名称:xxxxxx获取指定任务爬取的所有url的接口访问链接:http://IP:PORT/crwalTask/findUrlExceptionById?ctIdctIdVal&timetimeVal&limitlimitVal传入参数类型:String,int参数内容:返回…

java画好看坦克_坦克大战第一节——画出自己的坦克(新手篇)

刚刚开始学习java,对java不是很熟悉,但是自己的兴趣挺喜欢java。现在自己在自学java做一个小游戏,坦克大战。自己现在完成了画出自己的坦克和坦克的移动方向。希望各位大神指导一下我这个刚刚学java的新手小白。我会每完成一个阶段&#xff0…

java中timer类包_Java~util包中Timer的使用, 演示cancel方法 和 对比schedule和scheduleAtFixedRate方法...

TimerTimer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类执行计划任务的代码要放人TimerTask的子类中,因为TimerTask是一个抽象类。而且要重写其run方法 因为这是一个抽象方法.常见问题任务执行完了, 但进程并没有销毁,通过源码查看构造方…

centos eclipse java_CentOS7 安装 Eclipse

咳咳, 虽然大神的 Linux 都是命令行的, 但是谁让 LZ 是 LJ, 桌面开俩终端不觉得更好么。。。CentOS7 安装 Eclipse, 比在 Window 系统下安装 Eclipse 要复杂得多。。参考 : https://segmentfault.com/a/11900000026517…

java opencv orb_opencv python ORB算法

理论ORB(Oriented FAST and Rotated BRIEF)是一种快速特征点提取和描述的算法,这个算法是由Ethan Rublee, Vincent Rabaud, Kurt Konolige以及Gary R.Bradski在2011年一篇名为“ORB:An Efficient Alternative to SIFTor SURF”的文章中提出.ORB算法分为两部分&#…

php中define的参数_php中define的用法有哪些

php中define的用法:1、【define()】函数定义一个常量;2、定义常量名称及值,代码为【define(name,value,case_insensitive)】;3、定义一个大小写敏感的常量。php中define的用法:1、define()函数理解1define()函数定义一…

php 登陆微博,PHP调用微博接口实现微博登录的方法示例

在平时项目开发过程中,除了注册本网站账号进行登录之外,还可以调用第三方接口进行登录网站。这里以微博登录为例。微博登录包括身份认证、用户关系以及内容传播。允许用户使用微博帐号登录访问第三方网站,分享内容,同步信息。1、首…

2017php行情,2017年蔬菜行情特点及未来蔬菜价格走势分析

2017年蔬菜行情整体特点一、菜价走势前期低迷,后期逐渐回升:1.2017年1~10月的蔬菜平均价处于近3年同期的最低点;2.1~5月菜价创近5年同期最低。南方产区的实心菜花、散菜花、西兰花、团生菜、白萝卜、大白菜&#xff0c…

java实现layui静态表格分页,layui——数据表格分页实例

layui实现数据表格table分页功能,异步加载,表格渲染。总体流程:layui的数据表格设置分页参数开启可以从请求中看到如下图,所以我们需要在后端控制器接收分页数据page和limit进行操作,下面直接上代码分页链接框架&#…

mysql多列 groupby,MySQL多表查询之GroupBy

需求:根据主键id查询到该顾客最近的一次消费记录SQL代码如下:SELECTcbi.id,cbi.mob,cbi.identity_card,bcil.remark,bcil.orders_no,bcil.brand_no,bcil.with_date,bcil.scoreFROMcustomer_base_info cbiLEFT JOIN(SELECTA.customer_id,A.with_date,A.re…

java j2ssh替代jsch,jsch设置ssh协商算法优先级

最近接触jsch这个包,发现在默认情况下,jsch登录ssh的时候,协商的加密算法和mac算法都不是最高优先级的,这个时候需要手动配置一下算法列表,将强度高的调整在算法列表的前面,这样ssh链接的时候,如…

java 截取汉字首字母,java 取汉字首字母

有时候,可能会有一些类似这样的需求:对于这样的效果,我们可以有类似这样的解决方案:package bys.utils;import java.io.UnsupportedEncodingException;/*** Created by toutou on 2014/2/21*/public class ChineseCharacterHelper…

linux操作系统网络,网络安装linux操作系统

网络安装安装的准备首先配仓库然后需要安装的服务Yun y install tftp-serverYum y install dhcp开始实验配仓库安装tfpt包并进行配置Tftp-server dhcp tftp后,会在/var/lib/tftpboot这个文件,这个文件是作为linux安装的引导文件,将/mnt/isoli…