【TCP 协议】报文格式,数据可靠传输的机制(一)

本文涉及的产品
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 1个月
简介: 【TCP 协议】报文格式,数据可靠传输的机制(一)

  一、网络编程简介

真实的网络通信是基于 TCP / IP 五层网络模型实现,协议分层,自上而下,应用层-> 传输层-> 网络层-> 数据链路层->物理层,协议分层管理,规定下层协议为上层协议提供服务(接口 - API),上层协议可以直接调用下层协议,但是不允许跨层调用。除应用层以外,其余几层都被操作系统封装好了,并且提供一个传输层的接口(API)—— Socket, 那么应用层基于 Socket 开发,也就是我们常说的网络编程。

Socket ——套接字,主要提供两组传输层的协议接口。

1. 基于 UDP 传输协议的Socket 接口开发

2. 基于 TCP 传输协议的Socket 接口开发


简单讲述一下各个层级的协议主要的功能:

应用层:主要就是开发的程序需要具备一个联网,进行网络交互的功能和模式,这个一点是程序猿根据业务的实际需求设计开发的(选择使用那种传输层协议)。

传输层:主要负责数据在传输过程中的真实性,有效性等,例如:检测到数据没有传输成功那就再发一份,保证数据从源头到达目的,传输层给应用层提供服务。

网络层:主要负责数据的传输,利用IP 地址在网络中找到目的主机的位置,路由转发,提供一条可靠的传输路径。

数据链路层:主要给两个相邻的节点之间交互数据,例如将网卡中的数据交给物理层转化识别。

物理层:硬件设备,将二进制数据以各种形式传播,高低电平电信号——网线,光纤的光信号,以及广播等等。


二、TCP 传输协议简介

TCP(Transmission Control Protocol)是一种面向连接、可靠的传输协议,它在互联网协议模型中属于传输层,也是在日常开发中最广泛使用的协议,TCP 协议可以保证可靠的数据传输。

本篇博客将围绕着 TCP 协议如何保证可靠的数据传输来展开。

TCP 协议的特点

    1. 面向有连接 :传输数据之前,通信双方先建立可靠连接
    2. 可靠传输 :TCP 协议有超时重传的机制和确认应答机制等一系列的措施,当发现连接没有问题,但数据没有成功传输的时候会重新发送数据。
    3. 面向字节流:字面意思,使用字节流传输。
    4. 缓冲区:在进行网络数据通信时,用于存储待发送或已接收数据的缓冲区,有了缓冲区的概念,可以帮助协调发送方和接收方之间的数据传输速度,并最大限度地减少数据丢失或混乱的风险……
    5. 传输数据的大小不受限制:字节流,流式传输,前提是有连接。
    6. 全双工通信:通信双方都可以同时进行信息交互,例如:电话通信

    2. 1 TCP 协议报文格式

    我们学习一种协议最好是从该协议的数据报开始分析。

    TCP 报文的结构图:

    image.gif编辑

    仔细观察 TCP 数据报文结构图,我们会发现整个TCP 固定首部占20个字节,160 二进制位,但是根据我们画的结构图,所有的的节点相加只有 158 个二进制。

    在数据偏移的这一行,4 + 4 + 6 + 16 = 30位, 其实有两个二进制位是被 “浪费掉了”。

    TCP 报文解析:

    源端口和目的端口:两个端口各占 16个二进制位 端口可以认为是应用程序的身份标识,每一个入网的程序在启动的时就会随机的绑定一个端口号, 也可以手动给程序指定一个端口号,但是注意在同一主机中端口号不可重复,另一点,就是小于等于 1024 的端口号,被称为“知名端口号”,提供给一些名气比较大的服务器使用,例如:http 80。使用端口号用于确认信息的发送方是那个应用程序,信息的接收方是那个应用程序。

    序号和确认号:各占 32个二进制位 用于实现数据的可靠传输,所传送的字节流的每一个字节都会按顺序编号,保证数据传输的顺序和接收的顺序一样。序号表示当前发送的数据包的序号,确认号表示期望接收的下一个数据包的序号。

    发送方: 1. 哥们早安, 2. 周末有没有兴趣出去玩啊。

    接收方: 2. 周末有没有兴趣出去玩啊 ,1. 哥们早安。

    这种情况很明显是不可靠的的,序列号和确认号存在的意义就在于保证数据传输的顺序和接收的顺序一样。              

    数据偏移量:占4 个二进制位 确定 TCP 报文头部的长度,告诉接收端的应用程序,除去TCP 头部报文,身后数据部分从何处开始。

    标志位:包括ACK、SYN、FIN、RST、PSH、URG六种各占一个二进制位。

    如果为标志位置为 1表示 true 的意思。

    ACK用于确认收到数据包;

    SYN判断通信双方是否建立了连接;

    FIN用于关闭连接;

    RST用于重置连接;

    PSH用于提示接收方立即将数据推送给应用程序,而不是进入接收缓冲区;

    URG用于指示TCP包中有紧急数据

    窗口大小:用于流量控制,的校验和值是否正确,判断数据在传输的过程中是否受到影响(例如:电磁信号干扰表示发送方能够发送的未经确认数据的最大字节数,该字段可以用于 TCP 的流量控制,下文滑动窗口详细讲述。

    TCP校验和:用于检测TCP头和数据造成数据的偏差。保证数据的正确性。

    紧急指针:仅在URG标志被设置为 1 时才使用,用于指示紧急数据的末尾位置。

    保留:TCP报文头中的保留字段主要用于保留未来使用、兼容旧版本和防止出现错误,并为TCP协议提供了可扩展性和灵活性。


    三、TCP 保证数据可靠传输的机制

    3.1 确认应答

    确认应答:TCP 协议中,每次发送数据,接收方都会发送一个确认应答,告诉发送方数据已接收到了,如果发送方“迟迟”没有收到确认应答,就会认为数据没有发送成功,就会将数据重新传输。

    这也是 TCP 协议实现可靠传输最核心的机制。

    ACK(acknowledge)标志位用于确认收到数据包,会给予通信双方一个 ACK 反馈,利用这个反馈我们就发送端就可以判断接收端已经成功接收到信息了。同时这也意味着传输“效率”会有所降低,辛苦传输过去,还得等待对方反馈回来,如果迟迟没有反馈就会尝试重新发送一份~

    TCP的确认应答(ACK)是指接收方在成功接收到发起方发送过来的TCP数据包后,向发起方发送带有确认标志位的TCP报文段作为响应的一种机制。

    image.gif编辑


    在网络通信中也常常遇到信息“后发先至” 的情况,前两年qq 聊天就存在这个情况,我也遇到过这种情况,什么意思呢,当我给我的朋友发送一大堆消息,理论上来说,对方接受到的消息顺序应该与我发送消息的顺序一致,其实不然,消息有时候没按照我们预想的顺序来,这样就容易引起一些误会,举个例子:

    image.gif编辑

    网络通信中消息后发先至的原因可以有多种可能性,以下是几种可能性:

      1. 网络拥塞:当网络中的数据量过大时,会导致网络拥堵,从而导致一些消息被延迟发送或丢失,而其他消息在其之前被传输完毕并被接收方处理。这种情况下,即使先发送的消息比后发送的消息早,但后发送的消息可能会在先发送的消息之前到达接收方。
      2. 传输错误:网络传输过程中可能会出现传输错误,例如数据包损坏、丢失等等原因。如果一个数据包出现了错误,通过应答报文的反馈,发送方就需要将它重新发送,这可能会导致某些后发送的消息比先发送的消息更快地到达接收方。
      3. 排队延迟:当多个消息同时到达接收方时,接收方可能会将它们放入队列中进行处理。如果先发送的消息排在了后发送的消息前面,但由于其他因素(例如消息大小、处理时间等)导致后发送的消息比先发送的消息更快地被处理,那么后发送的消息就会先于先发送的消息到达接收方。

      为了解决“信息后发先至” 的情况,可以对消息进行编号,给发送的消息分配一个"序号" ,同时应答报文给出“确认序号”。

      image.gif编辑

      TCP 协议数据传输就是引入了序号和确认序号。

      TCP 协议会将每个字节的数据从前往后都进行编号,称之为“序列号”,因为TCP 是面向字节流传输的,不存在一条消息,两条消息的说法。

      image.gif编辑

      发送方的TCP 报文确认序号并没有多大的意义:

      image.gif编辑

      确认序号的规则:根据发送方发过来的数据的最后一个字节序号的下一个字节的序号。

      依据序号 1001 的含义:

      1. 如果应答报文的确认序号,< 1001 ,接受方给发送方透露的信息就是我已经收到

      2. 接收方接下来想向发送方索要从 1001 开始的字节流。

      使用这种机制,我们就可以保证数据传输的顺序,数据到达接收方也不是立马给到应用程序处理,上文提到TCP 有一个缓冲区的概念,缓冲区就可以将数据按照 “序号” 排序,即使数据在传输的过程中受到影响改变了数据传输的顺序,还有缓冲区兜底呢~ 保证应用程序读取数据,读到数据的顺序一定是和发送的顺序一样的。

      如果传输一切顺利,接收方就会反馈确认应答(反馈一个“TCP 首部”  其中ACK = 1)。


      3.2 超时重传

      数据在传输的过程中,难免会造成 “丢包” 问题(数据缺失),好在TCP 协议有确认应答的机制,如果那一部分的数据迟迟没有反馈应答(ACK),发送方就视为刚才的那部分数据丢包了,就会重新再发一遍,如果重发了好几次都没有得到接收方的应答,就会考虑连接这方面的问题,尝试重新建立连接等,下文讲述。

      超时重传:TCP协议中,如果发送方没有收到确认应答,就会进行超时重传。发送方会设置一个超时时间,如果在这个时间内没有收到确认应答,就会重新发送数据。

      发送方对于丢包的判定,是一定时间内,没有收到确认应答(带有确认标志位(ACK)的TCP报文段)—— ACK =  0

      这个时候存在三种情况:

      1. 数据直接在传输的过程中丢失,接收方没有收到数据,也就不会反馈 带有确认标志位(ACK)的TCP报文段。

      2. 接受方收到数据后,反馈带有确认标志位(ACK)的TCP报文段(TCP 首部信息包含 ACK),然后这个报文段丢了。

      3. 当发送方一定时间没有接收到反馈,就会触发超时重传,然后重传的数据也丢了

      第一种情况:

      image.gif编辑

      第二种情况:

      image.gif编辑

      第三种情况:

      image.gif编辑

      连续丢失多个数据包 “接收方无反馈” 的情况,大概率就是网络环境出现了非常严重的问题,TCP协议针对这种连续发多个数据都再丢失的情况,处理的思路是继续超时重传,但是每丢一次数据包,超时等待的时间就会越长(重传的频率降低了),如果连续多次传输超时重传都无法获取到接收方反馈的(ACK-TCP 首部信息包含 ACK),就尝试给通信双方重新建立连接,此时如果重新建立连接也是失败,TCP 协议就会放弃本次网络通信。


      四、总结

      TCP 传输控制协议,是互联网通信中使用最为广泛的协议,使用TCP 协议传输数据,数据安全可靠、真实性高,传输速度较快。

      学习一个协议的核心先熟悉他的报文格式。

      确认应答:

      当接收方收到发送方的数据时,会给予发送方一个带有 TCP 首部的字段,其中ACK = 1, 表示我已经收到数据。

      如果发送方一定时间内没有等到接收方反馈的确认应答,就会对该段“数据包” 进行重传,期间如果还是没有接收到反馈,发送方就会降低重传的频率,超过一定的次数,TCP 就尝试给通信双发重新建立连接,如果连接失败,就会终止本次的网络通信。

      TCP 为了解决数据发送的数据和接收的数据顺序不一样,所以给每一个字节进行编码,面向字节流传输嘛,序号字段描述了当前"数据包"的序列号, 发送端的确认序号没有实际的意义,接收方反馈的确认序号描述的期望下一个“数据包”的序号,如此发送方就知道下一次对方需要 “那一段” 数据,然后就是接收缓冲区的作用,传输的数据都有了编号,就可以利用“数据包”的序号对数据进行排序,这样数据的顺序也就得到了保障。

      遇到接收方数据接收成功,但反馈ACK 包丢失的情况,发送端超时重传,接收缓冲区就会对数据进行去重操作,保证应用程序拿到的数据是独一份的。

      相关实践学习
      深入解析Docker容器化技术
      Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
      相关文章
      |
      5月前
      |
      网络协议 算法 安全
      TCP协议(三次握手、流量控制、拥塞控制)
      TCP协议是一种可靠的传输层通信协议,通过三次握手建立连接,确保数据安全传输。流量控制通过接收窗口避免接收方缓冲区溢出,拥塞控制则利用拥塞窗口调节网络传输速度,防止网络拥堵。三者协同工作,保障TCP在复杂网络环境中实现高效、可靠的数据传输。
      1417 11
      EMQ
      |
      Linux 网络性能优化
      MQTT 5.0 报文解析 03:SUBSCRIBE 与 UNSUBSCRIBE
      在 MQTT 中,SUBSCRIBE 报文用于发起订阅请求,SUBACK 报文用于返回订阅结果。而 UNSUBSCRIBE 和 UNSUBACK 报文则在取消订阅时使用。相比于取消订阅,订阅操作更加常用。不过在本文中,我们仍然会一并介绍订阅与取消订阅报文的结构与组成。
      EMQ
      646 105
      MQTT 5.0 报文解析 03:SUBSCRIBE 与 UNSUBSCRIBE
      |
      12月前
      |
      存储 缓存 Linux
      【实战指南】用最小堆实现通用的高效定时器组件
      本文介绍了如何使用最小堆实现高效的定时器组件,以解决Linux应用开发中定时器资源有限的问题。文章详细描述了最小堆方式的实现原理,包括系统定时器、定时器任务和定时器任务管理三个类的设计与源码实现。测试结果显示,该方法能够准确触发定时任务,有效利用系统资源。总结部分强调了使用最小堆的优势,以及通过抽象类实现清晰的业务逻辑。
      392 101
      |
      缓存 网络协议 Shell
      网络协议格式 | 以太网帧、ARP数据报、IP数据报、UDP数据报、TCP数据报
      网络协议格式 | 以太网帧、ARP数据报、IP数据报、UDP数据报、TCP数据报
      1387 1
      |
      数据安全/隐私保护
      收藏,华三交换机V7软件版本升级方法(命令行版)
      收藏,华三交换机V7软件版本升级方法(命令行版)
      1014 1
      |
      缓存 网络协议 算法
      TCP 协议【传输层协议】
      TCP 协议【传输层协议】
      462 0
      |
      传感器 Python
      门禁管理系统工程是一个涉及硬件和软件集成的复杂系统,旨在控制人员的出入,并记录和管理相关数据。
      门禁管理系统工程是一个涉及硬件和软件集成的复杂系统,旨在控制人员的出入,并记录和管理相关数据。
      |
      负载均衡 Java 开发者
      Spring Cloud:一文读懂其原理与架构
      Spring Cloud 是一套微服务解决方案,它整合了Netflix公司的多个开源框架,简化了分布式系统开发。Spring Cloud 提供了服务注册与发现、配置中心、消息总线、负载均衡、熔断机制等工具,让开发者可以快速地构建一些常见的微服务架构。
      |
      传感器 网络协议 物联网
      如何使用Wireshark进行MQTT分析?
      如何使用Wireshark进行MQTT分析?
      1661 0
      如何使用Wireshark进行MQTT分析?
      |
      编译器 C++
      【C++11保姆级教程】delete和default关键字
      【C++11保姆级教程】delete和default关键字
      701 0