4.网络之TCP

TCP协议(传输层)

文章目录

  • TCP协议(传输层)
  • 1. TCP报文格式
  • 2. TCP相关机制
    • 2.1 确认应答机制
    • 2.2 超时重传机制
    • 2.3 连接管理机制(重点)
      • 2.3.1 三次握手
      • 2.3.2 四次挥手
    • 2.4 滑动窗口机制
    • 2.5 流量控制机制
    • 2.6 拥塞控制机制
    • 2.7 延迟应答机制
    • 2.8 捎带应答机制
  • 3. TCP异常处理
    • 3.1 粘包问题
    • 3.2 异常中断
      • 3.2.1 进程崩溃
      • 3.2.2 主机关机
      • 3.3.3 主机掉电
      • 3.3.4 网线断开
  • 4. TCP和UDP的对比

1. TCP报文格式

    TCP,即Transmission Control Protocol,传输控制协议。
在这里插入图片描述

  • 源/目的端口号:表示数据是从哪个进程来,到哪个进程去;
  • 32位序号:发送数据的第一个字节的序列号
  • 32位确认号:期望接收的序列号
  • 4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是15 * 4 = 60
  • 6位标志位:
    • URG:紧急指针是否有效
    • ACK:确认号是否有效
    • PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
    • RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段
    • SYN:请求建立连接;我们把携带SYN标识的称为同步报文段
    • FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段
  • 16位窗口大小:取流量控制和拥塞控制的较小值
  • 16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光包含TCP首部,也包含TCP数据部分。
  • 16位紧急指针:标识哪部分数据是紧急数据;
  • 40字节头部选项:包括选项列表结束、误操作、最大段长度、窗口扩展因子、时间戳

2. TCP相关机制

    TCP对数据传输提供的管控机制,主要体现在两个方面:可靠传输和效率,可靠传输是TCP 的初心。这些机制和多线程的设计原则类似:保证数据传输可靠的前提下,尽可能的提高传输效率。下面会介绍一些TCP协议的机制,帮助你理解TCP协议(传输层)。

2.1 确认应答机制

在这里插入图片描述
在这里插入图片描述

    确认应答机制是保证TCP可靠传输核心机制,TCP将每个字节的数据进行编号,每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发送。
    确认序号就是TCP报文中的32位确认序号,这个序号以可以确保应答报文和数据对应,在出现“后发先至”这样的情况时,程序可以按照正确的顺序组织数据。
    可靠传输,并不是指数据能够百分百到达对端,因为现实网络环境是非常复杂的,受到各种因素的综合制约。这里的可靠传输主要有两方面含义:

  1. 发送发发出数据后,能够知道对方是否收到数据。
  2. 如果对方没有收到,则可以采取“补救措施”,如重传等。

    如何区分一个TCP数据报是普通报文还是应答报文呢?TCP报文中ACK这一位为1,表示当前数据时一个应答报文,此时该数据报中的32位确认序号字段就会生效,反之同理。
在这里插入图片描述
    TCP可靠传输是通过以确认应答为核心,加以其他机制(超时重传,连接管理等)共同完成的。

2.2 超时重传机制

在这里插入图片描述

    确认应答是在,应答报文一定能被收到的理想情况下,但是应答报文也可能会丢包。那么为什么会产生“丢包”呢?
    我们发送的数据在发送途中经过路由器、交换机的转发,但是交换机的处理能力是有限的,如果同一时间的流量过大,路由器、交换机不会积压这些数据,而会之久丢弃一部分,只在自己的承受范围内处理数据,而被丢弃的数据也就永远的消失在了网络上了。
    如果应答报文(ACK)丢包了,那么发送方也就无法得知是否发送成功,此时可靠传输也就无从谈起了。引入“超时重传”机制,就可以在应答报文或者普通报文发出后,一段时间内无响应后,选择进行重新传输。
    超时重传的丢包有数据报丢包、应答报文丢包两种情况,而发送方根本无法区分这两种情况,会“一视同仁”的进行重传操作。由于重传后到达对端的概率会大大增加,如果重传多次,还未收到对端ACK,说明网络上已经出现了严重故障。TCP对重传成功到达对端这件事是抱有“悲观预测”的,超时的等待时间也会逐渐变长,当传输一定次数后还没有收到对端的ACK,此时就会触发TCP的重置连接操作。

2.3 连接管理机制(重点)

    我们之前说过TCP协议是有连接的,这个连接的建立过程,就是三次挥手(打招呼),断开连接就是四次挥手。
    这里“挥手” handshake,类似于打招呼,发起连接的一方向对方,发送不包含业务数据的数据报,用来唤起对方的注意,从而触发后续的操作。

2.3.1 三次握手

在这里插入图片描述
    1. 客户端主动发起建立连接的请求,向服务器发送一个不携带业务数据的数据报(syn 同步报文段)
    2. 服务器接收到客户端的建立连接请求后,会返回一个应答报文(ack),并且也会向客户端发送一个syn,并且这两个报文是合并为一个报文发送的(报文中SYN 和 ACK 都为1)【此时服务器验证了自己的接收能力】
    3. 客户端收到服务器发来的应答报文和同步报文段也会向服务器返回一个ack【客户端验证了自己的接收能力和发送能力】
    4. 服务器收到客户端发来的ack,连接建立完成。
    TCP的初心还是可报传输,如果此时网络已经存在重大故障,可靠传输也就无从谈起了。

三次握手核心作用

  1. 投石问路,确认当前无网络是否畅通
  2. 验证发送发和接收方的收发能力
  3. 让通信的双方在握手过程中,针对一些重要的参数进行协商。比如报文序号等系列参数。

2.3.2 四次挥手

在这里插入图片描述

    四次握手中的ACK和FIN一般不能合并,ACK和FIN的触发时机不同,ACK在内核收到数据后会立即进行响应,而FIN要在应用程序中调用close()方法后才能触发。这两个操作一般是不会合并的,但是在延时应答机制和捎带应答机制下,也可能合并。
    这里只介绍了,四次挥手完成,正常的连接断开,不分异常断开的情况会在下文的异常处理中介绍到。
    由于丢包状况的存在,前三次挥手若丢包都能正确触发重传,但是如果最后一次挥手丢包了,而客户端又早早地进入CLOSED状态(连接断开),那么服务器就会等待ACK报文,又因为客户端以及断开连接不会触发超时重传,所以服务器永远也等待不到客户端的ACK了。
    在这种情况下,客户端子啊第三次挥手之后不会立即进入CLOSED状态,而是进入TIME_WAIT状态,等待一段时间,若ACK丢了,就会触发服务器的超时重传,重发FIN,进而客户端再次进行ACK响应。
    这里的TIME_WAIT的等待时间一般会设为2*MSL,MSL是网络上两个节点的最大消耗时间,确保挥手留有客户端ACK到达服务器和ACK丢包服务器超时重传的时间。

2.4 滑动窗口机制

    前面介绍的确认应答、超时重传、连接管理机制都是为了保证可靠传输,而可靠传输必定要牺牲一定的效率,而滑动窗口机制则是一种”亡羊补牢“的措施。让TCP的效率尽可能的高一点。
    在原来的机制下,没发送一个TCP数据报都要等待对端返回ACK后才能继续发送,而滑动窗口机制则是先发送一批数据,对这一批数据进行集中等待ACK,收到某个ACK窗口就可以往下滑动。在不等待的情况下,批量发送多少数据的上限成为”窗口大小“。
在这里插入图片描述
    在这个过程中如果产生丢包,有两种情况。

    一是ACK丢了,这种情况是不需要进行重传的,因为ACK在滑动窗口机制下被赋予了新的含义,是从xxx个字节之前的数据都收到了,如果在这之前的ACK丢失并不会影响到现在的判断。在这里插入图片描述
    二是数据丢了,数据丢失后,接受方会将这个之后的数据丢弃,不断向发送方索要该序号的数据,等待该数据报的到来。

在这里插入图片描述
    何时回触发TCP的滑动窗口机制呢?如果收发双方传输的数据量比较小,也不平频繁,此时不会触发滑动窗口机制,任然是按照确认应答和超时重传机制传输。但是,如果收发双方传输的数据量较大,比较频繁,就会触发滑动窗口机制,进行批量发送,快速重传。

2.5 流量控制机制

    通过滑动窗口机制传输数据,效率得到了一定的提升,但是这个窗口也不是越大越好,为了控制窗口大小,引入了流量控制机制和拥塞控制机制。分别从接收方的处理能力和网络路线的状况来优化窗口大小,动态调整。

    由于接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。TCP支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控(Flow Control) - 生产者消费者模型
    流量控制机制是站在接收方的角度,反向制约发送方的发送速度,发送方的发送速度,不应该超过接收方的处理能力。发送方会根据接受方缓冲区的剩余空间大小,来作为衡量窗口大小的指标,这就意味着:

  • 剩余空间越大,消费速度越快,处理能力越强,窗口大小越大,发送速度更快
  • 剩余空间越小,消费速度越慢,处理能力越弱,窗口大小越小,发送速度更慢

在这里插入图片描述
    TCP报文中的16位窗口大小,就是用于接收方将自己当前的缓冲区大小反馈给发送方。这个窗口大小只有16位,这是否以为这最大只能是64kb呢?TCP报文中的选项中,有一部分叫做窗口扩展因子,如果当前传输情况理想,窗口是可以更大的。
在这里插入图片描述
    在这个过程中如果接收方的接收缓冲区满了,那么发送方就会停止发送,等待接收方对接收缓冲区内的数据进行处理,那么停止多久呢?此时发送方会周期性的发送一个不携带业务数据的”窗口探测包“,这个数据报知识为了得到接收方的ACK,从而判断接收方的接收缓冲区的大小,从而做出进一步判断。

2.6 拥塞控制机制

    流量控制机制是站在接收方的数据处理能力视角上对窗口大小进行优化,这里的拥塞控制则是站在网络传输路径是否畅通(通信中间节点的情况)对窗口大小进行优化,最终的窗口大小要取两者的较小值。
    由于木桶效应,发送速度收到整个通信状况中的最短板决定,所以这里的拥塞控制会在不大于接收方的处理能力的情况下,逐渐增大 ,增大到某个临界点,出现丢包时再将窗口大小进行调整,此处也是动态变化的。

    如果在刚开始阶段就发送大量的数据,可能引发问题。因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。TCP拥塞控制是一种慢启动机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据;我们先看一个经典的拥塞控制。
在这里插入图片描述
    刚开始从一个比较小的速度开始发送,指数级递增,当达到某个阈值时停止指数增长,改为线性增长(假发增大),如果出现拥塞,那么直接从速度归零重新进行“慢开始”。
    这种经典的拥塞控制一旦遭遇拥塞,那么就会重新慢开始,下降速度太快,有一种开进版的拥塞控制,遭遇拥塞后,在原有阈值的基础上,计算出新的阈值,从这个新的阈值开始线性增长。

2.7 延迟应答机制

    如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小。
在保证网络不会拥塞的情况下,窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率。
    当收到发送方的数据时,不必立即反馈ACK,等待接收方进行数据处理,让缓冲区空间剩余大小进行增长,此时窗口就会尽可能的大。

2.8 捎带应答机制

    捎带应答实在延时应答的基础上,进一步做出的效率上的优化,延时应答后,将应答报文和数据报文进行合并,一次性发送给发送方。减少了中间的封装和分用的开销。在这种情况下,TCP断开连接的四次挥手也是可能三次挥完的。

3. TCP异常处理

3.1 粘包问题

    由于TCP是面向字节流的,在接收方接收到数据从缓冲区读取数据时,就无法区分应用层数据报之间的边界。如果同时到来多个,那么就可能出现粘包问题。
在这里插入图片描述
在这里插入图片描述
    相比较之下,UDP则是面向数据报的,UDP的接收缓冲区中是一个个的DatagramPacket对象,应用程序读取时可以明确的知道边界,就不会出现粘包问题。
在这里插入图片描述
    要解决TCP的粘包问题,我们只需要明确TCP->应用层数据包间的边界。

  1. 使用分割符 如 \n这种行文本
  2. 使用长度进行标识,在数据包之前加上长度,让应用程序明确一个包多大。

    此处的应用层协议可以自定义,如xml、json、protobuffer等(边界明确的),当然也可以自定义应用层协议。

3.2 异常中断

3.2.1 进程崩溃

    进程没了,异常终止了。进场的文件描述符表也就释放了。相当于调用socket.close(),此时就会触发FIN,对方收到之后,会返回FIN和ACK,这边再进行ack (正常的四次挥手断开连接的流程)tcp的连接,可以独立于进程存在。(进程没了,tcp连接还在)

3.2.2 主机关机

    在进行关机操作时,会先触发强制关闭进程,相当于进程崩溃。此时就会触发FIN,对方收到就就会返回 ACK和FIN,但不仅仅是进程结束了,操作系统也关闭了。

  • 如果操作系统关闭之前对端返回的ACK和FIN到了,此时系统还是可以返回ACK进行正常的四次挥手,正常断开连接。
  • 如果操作系统关闭之前对端返回的ACK和FIN还未到,ACK和FIN迟到后,操作系统已经关机,无法对ACK和FIN进行回应,站在发送方的角度,以为是丢包了,然后进行重传,多次重传后都没有响应,也就放弃连接了。

3.3.3 主机掉电

    主机掉电是一瞬间的事情,对端是来不及反应的。

  • 接收方掉电:发送方就会一直等待ACK,然后触发超时重传,进一步触发TCP的连接重置,发出复位报文段,如果复位报文段发出后没有得到响应,连接也就会断开
  • 发送方掉电:此时接收方是无法区分是发送方没有进行数据发送还是挂了,TCP中提供了”心跳包“机制,接收方会周期性的给发送方发送一个心跳包(不携带业务数据)期待得到对端的应答,如果没有得到应答,在重复多次后,连接也会断开。

3.3.4 网线断开

    假设A给B发送数据,一旦网线断开,A就会触发超时重传 => 重置连接 => 断开连接。B就会 触发心跳包 => 对端未响应 => 断开连接【TCP的心跳包周期较长】

4. TCP和UDP的对比

    TCP 的优势在于可靠传输,TCP可以适用于绝大部分场景。
    UDP的优势在于效率跟高,适用于对”可靠性不敏感,效率敏感“的场景,同一个机房内部的数据传输就会优先考虑UDP,因为同一个机房内丢包的概率不大,希望数据能够更快的传输。在需要广播的场景下UDP也有得天独厚的优势,UDP天然支持广播,所谓广播就是将数据发给当前局域网的所有设备。

    如果本篇文章对你有帮助,请点赞、评论、转发,你的支持是我创作的动力。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux工具git版本控制器介绍

git介绍 ​ git就是一个版本控制器,是由Linux之父写的开源软件,功能就是保存每个版本的内容。将被管理的内容(文本),按照变化来进行管理的软件,你需要哪一个变化的版本都可以找到。 git是一个软件&#x…

ATE新能源汽车充电桩自动负载测试系统

随着新能源汽车的普及,充电桩的需求也在不断增加,为了确保充电桩的性能和安全性,对其进行负载测试是非常重要的。ATE新能源汽车充电桩自动负载测试系统是一种专门用于检测充电桩性能的设备,它可以模拟各种实际使用场景&#xff0c…

打造高效运营底座,极智嘉一体化软件系统彰显科技威能

在仓储成本和物流需求日益增加的今天,创新且高效的物流机器人解决方案能够显著提升物流运营效率,降低物流成本,实现智能化、精益化、一体化的物流管理。全球仓储机器人引领者极智嘉(Geek)以「一套系统,天生全能」为准则&#xff0…

数据集:机器人理解世界的关键

原创 | 文 BFT机器人 传统的机器人和工业自动化解决方案已经颇有成效。在工厂中入驻自动化机器人可以快速地帮助工人们完成长时间重复劳动的任务。随着用工成本上涨、技能人才短缺、工作环境恶劣等问题的凸显,社会更迫切地需要采用自动化设备代替人工来完成该类操作…

又要报销了,还在手动下载整理发票吗?

大多数公司都是每个月定期提交报销,一般报销用的发票都是电子发票发到邮箱,每次要报销时都需要登录邮箱,点开邮件,一个个下载整理,工作量不大,但是发票多了也着实很烦。这个月终于下决心把这个过程自动化一…

《005.SpringBoot+vue之学生选课管理系统01》

《005.SpringBootvue之学生选课管理系统01》 项目简介 [1]本系统涉及到的技术主要如下: 推荐环境配置:DEA jdk1.8 Maven MySQL 前后端分离; 后台:SpringBootMybatis; 前台:vueElementUI; [2]功能模块展示: 管理端 1…

BO(Business Object)是一种用于表示业务对象的设计模式

1、Service层 BO 1.1、FruitService接口 package com.csdn.fruit.service; import com.csdn.fruit.dto.PageInfo; import com.csdn.fruit.dto.PageQueryParam; import com.csdn.fruit.pojo.Fruit; public interface FruitService {PageInfo<Fruit> getFruitPageInfo(Page…

C++性能优化笔记-6-C++元素的效率差异-7-类型转换

C元素的效率差异 类型转换signed与unsigned转换整数大小转换浮点精度转换整数到浮点转换浮点到整数转换指针类型转换重新解释对象的类型const_caststatic_castreinterpret_castdynamic_cast转换类对象 类型转换 在C语法中&#xff0c;有几种方式进行类型转换&#xff1a; // …

unity【动画】脚本_角色动画控制器 c#

首先创建一个代码文件夹Scripts 从人物角色Player的基类开始 创建IPlayer类 首先我们考虑到如果不挂载MonoBehaviour需要将角色设置成预制体实例化到场景上十分麻烦&#xff0c; 所以我们采用继承MonoBehaviour类的角色基类方法写代码 也就是说这个脚本直接绑定在角色物体…

VBA之正则表达式(44)-- 拆分商品和规格

实例需求&#xff1a;商品组清单保存在A列中&#xff0c;现需要将其拆分为商品名称&#xff0c;保存在从B列开始的后续单元格中&#xff0c;部分商品包含规格&#xff0c;并且多种规格属性使用了逗号分隔&#xff0c;因此无法直接使用Excel分列功能完成数据拆分。 示例代码如下…

“第六十一天”

这三个也算一类的&#xff0c;减和加的处理差不多&#xff0c;不过这个题多了限制是被减数大于减数&#xff0c;要是想再完整一点&#xff0c;可以把小于的情况也考虑进去&#xff0c;不过这个我是如果被减数小于减数的话&#xff0c;我就用减数加被减数&#xff0c;然后最后打…

【MySQL数据库】 四

本文主要介绍了mysql数据库的几种常见的约束. 一.数据库约束 我们希望存储的数据是靠谱的,mysql提供一些机制来辅助我们自动的依赖程序对数据进行检查 . 这类查数据的机制,就是约束 一旦约束好了,后续在进行增 删 改的时候,mysql就会自动的对修改的数据做出检查,如果不符合…

wscat

wscat 是一个用于 WebSocket 通信测试的命令行工具 安装wscat flynnsinflynnsin:~$ sudo npm install -g wscat loadDep:ws → afterAdd ▄ ╢████████████████████████████████████░░░░░░░░░░░░░░░░░░░░░░░…

爱上C语言:函数递归,青蛙跳台阶图文详解

&#x1f680; 作者&#xff1a;阿辉不一般 &#x1f680; 你说呢&#xff1a;生活本来沉闷&#xff0c;但跑起来就有风 &#x1f680; 专栏&#xff1a;爱上C语言 &#x1f680;作图工具&#xff1a;draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话&#xff0c;还请…

大数据毕业设计选题推荐-旅游景点游客数据分析-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

修复RGBA的png为RGB的png

修改IHDR里面的color type 修改IHDR的crc 删除sBit和sRGB两个chunk

linux中各种最新网卡2.5G网卡驱动,不同型号的网卡需要不同的驱动,整合各种网卡驱动,包括有线网卡、无线网卡、Wi-Fi热点

linux中各种最新网卡2.5G网卡驱动&#xff0c;不同型号的网卡需要不同的驱动&#xff0c;整合各种网卡驱动&#xff0c;包括有线网卡、无线网卡、自动安装Wi-Fi热点。 最近在做路由器二次开发&#xff0c;现在市面上卖的新设备&#xff0c;大多数都采用了2.5G网卡&#xff0c;…

crond服务

目录 一、crond服务基础知识 1、crond服务介绍 2、查看crond服务的状态 3、crond服务配置文件详解 4、额外的配置文件目录 二、crond服务基础命令 1、crond服务使用 2、 管理和操作 crond 服务 3、crond服务命令举例 一、crond服务基础知识 1、crond服务介绍 1、crond…

bug: https://aip.baidubce.com/oauth/2.0/token报错blocked by CORS policy

还是跟以前一样&#xff0c;我们先看报错点&#xff1a;&#xff08;注意小编这里是H5解决跨域的&#xff0c;不过解决跨域的原理都差不多&#xff09; Access to XMLHttpRequest at https://aip.baidubce.com/oauth/2.0/token from origin http://localhost:8000 has been blo…

HarmonyOS 数据管理与应用数据持久化(二)

通过键值型数据库实现数据持久化 场景介绍 键值型数据库存储键值对形式的数据&#xff0c;当需要存储的数据没有复杂的关系模型&#xff0c;比如存储商品名称及对应价格、员工工号及今日是否已出勤等&#xff0c;由于数据复杂度低&#xff0c;更容易兼容不同数据库版本和设备…