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天然支持广播,所谓广播就是将数据发给当前局域网的所有设备。

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

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

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

相关文章

登录Tomcat控制台,账号密码输入正确但点击登录没反应不跳转到控制台页面

在tomcat-users.xml里面可以查看登录tomcat控制台的账号密码,如果账号密码输入正确还是登录不进去,则很有可能是tomcat的账号被锁了(可在catalina.xxx.log里面查看)。tomcat账号被锁定后默认情况是不访问控制台后5分钟自动解锁&am…

访问者模式-操作复杂对象结构

商场里有许多的店铺,大致分为服装区、饮食区及休闲区,每天都会有络绎不绝的不同角色(打工人、学生、有钱人)的人来逛商场。商场想开发个系统用来模拟这些人的在这些店铺的行为。 public class SuperMarket {public static void m…

立创eda专业版学习笔记(8)(运行模式)

以前没注意过这个问题,我有2台电脑,都能登录eda专业版,但是一台是全在线模式,另外一台是半离线模式,虽然是同一个账号,但是打开里面的工程会发现,两边的工程完全不同,因为一台的工程…

【UE5 Cesium】actor随着视角远近来变化其本身大小

效果 步骤 1. 首先我将“DynamicPawn”设置为默认的pawn类 2. 新建一个父类为actor的蓝图,添加一个静态网格体组件 当事件开始运行后添加一个定时器,委托给一个自定义事件,每2s执行一次,该事件每2s获取一下“DynamicPawn”和acto…

kafka问题汇总

报错1: 解决方式 1、停止docker服务   输入如下命令停止docker服务 systemctl stop docker 或者service docker stop1   停止成功的话,再输入docker ps 就会提示出下边的话: Cannot connect to the Docker daemon. Is the docker daem…

YoloV5训练V3Det数据集实战

摘要 V3Det:一个庞大的词汇视觉检测数据集,在大量真实世界图像上具有精确注释的边界框,其包含13029个类别中的245k个图像(比LVIS大10倍),数据集已经开源! 图片的数量比COCO多一些,…

云计算的大模型之争,亚马逊云科技落后了?

文丨智能相对论 作者丨沈浪 “OpenAI使用了Azure的智能云服务”——在过去的半年,这几乎成为了微软智能云最好的广告词。 正所谓“水涨船高”,凭借OpenAI旗下的ChatGPT在全球范围内爆发,微软趁势拉了一波自家的云计算业务。2023年二季度&a…

嵌入式C语言自我修养《数据存储与指针》学习笔记

目录 一、数据类型和存储 1.大端模式和小端模式 2.有符号数和无符号数 二、数据对齐 1.为什么要数据对齐 2.结构体对齐 3.联合体对齐 三、数据的可移植性 四、 Linux内核中的size_t类型 五、typedef的使用 1. typedef的基本用法 2.使用typedef的优势 3. typedef的作用域 六…

【SQL篇】一、Flink动态表与流的关系以及DDL语法

文章目录 1、启动SQL客户端2、SQL客户端常用配置3、动态表和持续查询4、将流转为动态表5、用SQL持续查询6、动态表转为流7、时间属性8、DDL-数据库相关9、DDL-表相关 1、启动SQL客户端 启动Flink(基于yarn-session模式为例): /opt/module/f…

Java_类和对象详解

文章目录 前言简单认识类类定义和使用类的实例化引用的一些注意事项 类和对象的说明及关系this引用为什么要有this引用this应用this特性 构造方法构造特性及应用用this简化用idea编译器快捷创建构造 封装封装的概念访问限定符 封装的扩展-包包的概念导入包中的类自定义包常见的…

Skywalking介绍

一个优秀的项目,除了具有高拓展的架构、高性能的方案、高质量的代码之外,还应该在上线后具备多角度的监控功能。现在企业中的监控服务也有很多,Skywalking除了提供多维度、多粒度的监控之外,也提供了良好的图形化界面以及性能剖析…

LeetCode 面试题 16.17. 连续数列

文章目录 一、题目二、C# 题解 一、题目 给定一个整数数组,找出总和最大的连续数列,并返回总和。 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。…

DDD学习笔记

1)ddd: 软件复杂性的应对之道。 但是不是说:redis这种不会使用。 开发过程中,一直面临的一种复杂性。 是一种架构思想: 领域之间的组合。 让开发软件具有搭积木的感觉。 领域的核心是边界。 以领域划分为基础。 以通用语言为建设…

持续集成交付CICD:安装Jenkins Slave(从节点)

目录 一、实验 1.安装Jenkins Slave(从节点) 二、问题 1.salve节点启动jenkins报错 2.终止命令行后jenkins从节点状态不在线 一、实验 1.安装Jenkins Slave(从节点) (1)查看jenkins版本 Version 2.…

c语言进阶部分详解(《高质量C-C++编程》经典例题讲解及柔性数组)

上篇文章我介绍了介绍动态内存管理 的相关内容:c语言进阶部分详解(详细解析动态内存管理)-CSDN博客 各种源码大家可以去我的github主页进行查找:唔姆/比特学习过程2 (gitee.com) 今天便接“上回书所言”,来介绍《高质…

ElasticSearch 实现 全文检索 支持(PDF、TXT、Word、HTML等文件)通过 ingest-attachment 插件实现 文档的检索

一、Attachment 介绍 Attachment 插件是 Elasticsearch 中的一种插件,允许将各种二进制文件(如PDF、Word文档等)以及它们的内容索引到 Elasticsearch 中。插件使用 Apache Tika 库来解析和提取二进制文件的内容。通过使用 Attachment 插件&a…

Qt的事件

一、鼠标按下事件 //鼠标按下事件,获取屏幕位置,并显示,移动显示框 void Widget::mousePressEvent(QMouseEvent *event) {if(event->button() ! Qt::LeftButton){return ;}QPoint point event->pos();QPointF winPt event->…

Python学习-shutil模块和OS模块学习

shutil模块 针对文件的拷贝,删除,移动,压缩和解压操作 # 1.copyfileobj只能复制文件内容,无法复制权限#复制文件时,要选择自己有权限的目录执行操作,创建的文件会根据系统umask设定的参数来指定用户权限 s…

首发scitb包,一个为制作统计表格而生的R包

目前,本人写的第3个R包scitb包已经正式在R语言官方CRAN上线,scitb包是一个为生成专业化统计表格而生的R包。 可以使用以下代码安装 install.packages("scitb")scitb包对我而言是个很重要的R包,我的很多想法需要靠它做平台来实现&a…

项目实战:优化Servlet,把所有围绕Fruit操作的Servlet封装成一个Servlet

1、FruitServlet 这些Servlet都是围绕着Fruit进行的把所有对水果增删改查的Servlet放到一个Servlet里面,让tomcat实例化一个Servlet对象 package com.csdn.fruit.servlet; import com.csdn.fruit.dto.PageInfo; import com.csdn.fruit.dto.PageQueryParam; import c…