重温TCP通信过程

文章目录

    • 1. 慢启动
    • 2. 拥塞避免
  • 3. 快速重传和快速恢复

初识tcp报文

我们先来简单认识一下报文的格式,具体理解需要后面详细介绍

  1. 源端口和目的端口:顾名思义就是标识传输双方的信息
  2. 首部长度:指的是TCP报头的长度,换句话来说,我们需要用一个属性来描述报头的长度,就说明TCP的报头是变长的
  3. 选项:实际上这里翻译为"可选项"更加准确,这是TCP为了适应复杂的网络环境和更好的服务应用层而进行设计的,TCP选项部分最长可以达到40byte ,再加上TCP选项外的固定的20byte字节部分, TCP的最长头部可达60byte
  4. 序列号:在一个TCP连接中传输的字节流中的每一个字节都按顺序编号,该字段表示本报文所发送的数据的第一个字节的序号
  5. 确认号:表示期待收到对方下一个报文段的第一个数据字节的字段,例如当确认号为N,表示序列号N-1之前的所有数据都已全部接收到
  6. 窗口:通知发送端,接收端可接受的空间大小
  7. 校验和:发送端计算发送的TCP报文段的校验和,接收端对接收到的TCP报文段,验证其校验和,如果不一致,说明数据包在发送端和接受端之间传输的时候发生了变动,此时该TCP报文会被直接丢弃
  8. 保留位: TCP报头里,提前申请好的一块空间,这个空间暂时用不上,但是说不定以后就能够用的上(万一以后TCP要扩展一些新的功能,就可以用这个保留位来表示了)
  9. 6位标志位:他们中的一位或者多位可以同时设置为1,用于说明该报文性质,其中下面三个字段需要格外注意:
    1. ACK,仅当ACK为1的时候,确认号字段才有效,TCP规定,当连接建立之后,所有传输的报文都必须将ACK设置为1
    2. SYN,仅在三次握手建立TCP连接时有效,当SYN=1,ACK=0时,表明这是一个连接请求报文,若对方同意连接,则在响应报文中设置SYN=1 和 ACK = 1
    3. FIN,用来释放一个连接,当FIN=1时,表示此报文的发送方的数据已经发送完毕,并要求释放连接

三次握手建立连接

为了确保通信双方都能**确认对方的存在和可用性**,并且**数据能够被正确的传输和接收**,TCP要求通信双方建立一条可靠的通信连接

三次握手是TCP协议中用于建立可靠连接的过程:

  1. A向B发送一个SYN报文,请求建立连接

  1. B收到A的SYN报文后回复一个SYN + ACK的报文

  1. A收到B的SYN报文之后,回复一个ACK报文

  1. B接受到ACK报文之后,表示一个TCP连接就建立好了

如果对上面的建立连接过程不懂,可以看下面的例子:

那么此时就很容易发现,为什么一定要三次握手??两次行不行??

答案是否定的,因为只有经过最后一次交互,B才能知道对方的接受能力和自己的发送能力是没问题的

分段机制

TCP经过三次握手之后就能发送数据了,但是一般网络不能连续的传输任意长的数据,因此,发送方A将需要传输的消息分割成小快,按照顺序分别发送,这些小块就是数据包

B接受到数据报之后,经过校验和校验无误之后,开始将收到的数据包进行重新组装,还原成原始消息

但是可想而知,数据包组装需要安装分割前的顺序进行拼接,但是我们确不能保证B接受数据包的顺序和我们传输的顺序是一致的,因为在网络传输过程中会经过很多交换机和路由器的传输,而不同的设备传输速度,负载情况,网络拥堵等因素都会影响数据包的传输顺序

为了解决这个问题,TCP在数据包的头部定义了一个序列号的字段,用于对在一个TCP连接中传输的字节流中的每一个字节按顺序进行编号,就可以解决乱序的问题了

确认应答+超时重传机制

为了保证所有的数据包都能够正确接收,TCP引入了确认应答机制

B在接收到数据之后,会回复一个携带确认号的确认包,也就是ACK包,A接收到ACK报之后,再发送下一个数据包

如果结果一段等待时间之后,发送包无法知道数据包的情况,则可能出现以下的情况:

解决这个问题的一般方法是超时重传,A在发送数据包之后,不会一直等待,而是启动一个重传定时器,定时到期之后未收到数据包,就会认为数据包丢失了,从而重传数据包

滑动窗口机制

在上面确认应答机制的情况下,A只有当接收到B回复的ACK包之后,才能继续发送下一个数据包

在这种场景下,发送方大多数时间都是在等待接收方的ACK中,极大的影响了通信的效率

一种解决问题的方法就是滑动窗口,这种机制允许发送方连续发送多个数据包而无需等待

TCP使用一个称为发送窗口的变量,表示无需等待确认即可发送的数据包的数量

那么发送窗口的大小设置为多少才是合理的呢?

如果太小,那就和我们上面简单的确认应答机制没什么区别了

如果太大,接收方可能会来不及处理而丢失数据包,得不偿失

TCP使用滑动窗口的机制,要求接收方维护一个可处理的接收窗口,发送方根据接收窗口来调整发送窗口的大小,从而根据接收方的接受能力来动态控制流量

通信双方每次在发送数据时,都会在TCP报头中携带窗口的大小.表示自己当前的接收能力

前面我们说过为了保证所有数据包都被收到,要求每个数据包接收到之后都要返回一个ACK包

延时应答 +累计确认

在滑动窗口的场景下,如果每个数据包都要回复一个ACK包的话,过多的确认包会消耗网络资源,降低网络利用率

对于累计确认来说,就是如果接收方返回确认号为N的ACK包,则表明N之前但不包括N的数据包已经全部接收到了

而延迟确认指的是接收方在接收到数据包之后不立即回复,而是延迟等待一段时间,这样在延迟的时间内收到多个连续的包可以累计成一个ACK确认

通过这两种方式,减少了ACK包的数量,提高了网络利用率

快速重传机制

前面说过,接收方等待一定时间之后,如果未接收到ACK包,就会触发超时重传

但是还是需要等待一定时间,降低了传输效率

TCP引入了快速重传机制:当接收方连续收到三个相同的确认号的时候,就会触发快速重传,立即重传数据包,而不必等待超时时间

拥塞控制

滑动窗口只考了接收方的处理能力,发送端根据接收窗口的大小发送数据,而忽略了网络的负载情况

随着网络连接数量的增加,必然会造成网络拥堵,就可能引起大量的超时重传,形成恶性循环,造成整个网络不可用

因此要进行拥塞控制来避免这种情况的发生

拥塞控制的主要思路是防止过多数据注入网络,以避免网络出现负载过大,也就是要根据网络拥塞情况,对发送数据包的数据进行控制

TCP定义了一个拥塞窗口的变量,如果网络拥堵就减少拥塞窗口,畅通就增加拥塞窗口

我们前面说过,发送窗口的大小等于接收窗口的大小

现在引入拥塞窗口之后,发送窗口的大小就等于拥塞窗口和接收窗口中的最小值,这样就能有效控制网络的发送效率

其中Reno算法是当前应用最广泛的拥塞控制算法

主要包含慢启动、拥塞避免、快速重传、快速回复

1. 慢启动

刚接入网络的时候先发送少量数据包,探测网络情况,然后再一点点逐步提高发送包的数量

2. 拥塞避免

慢启动的指数级别增长不可能一直持续下去,当发生网络拥堵的时候,慢启动增长就会结束

同时TCP定义了一个慢启动阈值的变量,当拥塞窗口超过这个阈值,就会进入拥塞避免模式,结束指数级增长

假设我们这个阈值是8,当超过8之后,就会以1的数量级增加,以线性增长,这种线性增长的方式相对于指数增长的方式更加稳定,可以避免网络拥塞的发生

但是也不能一直增长,和慢启动一样,当发生网络拥堵的时候,拥塞窗口的增长就会结束

那么网络拥堵是怎么感知到的?? 同时拥塞窗口又怎么调整呢?

TCP是通过丢包来感知网络拥堵状态的

丢包可以分为两种

  1. 超时丢包

也就是经过一段等待时间之后,还没收到ACK包,这种情况说明网络拥堵比较严重,TCP会进入慢启动模式,并将慢启动阈值设置为出现丢包时候的拥塞窗口的一般,重新开始慢启动,后拥塞避免…

  1. 第二种是收到三次重复的ACK

此时就会认为之前发送的数据包丢失,这种情况下认为当前网络发生了轻微拥堵,此时拥塞窗口减小的幅度不会像超时丢包那么大,会执行快速重传和快速恢复算法

3. 快速重传和快速恢复

  1. 将慢启动阈值设置为当前拥塞窗口的一半,并重传丢失的数据包
  2. 将拥塞窗口设置为当前慢启动阈值加上3,这是因为,发送方收到了3个相同的ACK说明当前已经有三个数据包到达了接收端,网络的"在途数据量"减少了三个,此时将拥塞窗口加上3,就是适当将拥塞窗口尽可能的变大些
  3. 再次收到重复的ACK,将拥塞窗口增加1
  4. 当收到新的数据包的ACK的时候,将拥塞窗口设置为第一步设置的阈值的值,此时快速恢复结束,再次进入拥塞避免阶段

实际上第一次学我也是云里雾里的,这里有必要通过一个例子来解释一下我的理解:

  1. cwnd(拥塞窗口)=9,此时发送9个数据包(序号1-9)
  2. 假设5数据包丢失,但是报文6~9正常到达接收端
  3. 接收端每次接受到6~9的数据包,都会回复一个ACK=5,发送端连续收到了3个ACK
  4. 触发快速重传,立即重传丢失的报文5,同时更新阈值(ssthresh= cwnd / 2 = 4.5 = 4)
  5. 进入快速恢复阶段,设置cwnd = ssthresh+3 = 7,加3是因为,由于已经收到了3个重复的ACK,说明(6,7,8)报文已经成功到达了接收端,可以将窗口向上提3个大小,不会导致下降太多
  6. 在等待ACK=5的报文阶段,允许发送新的报文(10~13),此时又会收到连续的重复的ACK=5,此时每收到一个就将cwnd+1,原因和5一样
  7. 当收到新的ACK=6,说明网络恢复,此时重置窗口cwnd=4,退出快速回复,进入拥塞避免阶段,为什么要重新降低?? 我觉得有以下原因
    1. 快速恢复阶段通过临时增大窗口(**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">cwnd = ssthresh + 3</font>**)来维持数据传输,但此时网络可能仍处于敏感状态,若继续保持这个值,可能会导致拥塞循环
    2. 重置窗口后,TCP进入拥塞避免阶段,确保窗口增长更平滑,避免突然的流量激增。

四次挥手结束通信

TCP是全双工的,每个方向可以同时传递数据,因此每个方向需要单独的关闭
  1. A方发送FIN来终止这个方向上的传输,待对方确认(返回ACK)后进入半关闭状态(也就是说A此时还能接受B发送来的数据 ,因为只是A认为自己结束了,B可能还在发送)
  2. B发现自己数据发送完毕之后,发送给AFIN来终止传输,待A确定后(返回ACK)终断连接

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

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

相关文章

力扣HOT100之链表:23. 合并 K 个升序链表

这道题我是用最淳朴最简单的思路去做的&#xff0c;用一个while循环持续地将当前遍历到的最小值加入到合并链表中&#xff0c;while循环中使用一个for循环遍历整个指针数组&#xff0c;将其中的最小值和对应下标记录下来&#xff0c;并将其值加入到合并链表中&#xff0c;同时对…

Spring Boot 支持政策

&#x1f9d1;&#x1f4bb; Spring Boot 支持政策 ✒️ Andy Wilkinson 于2023年12月7日编辑本页 32次修订 &#x1f4cc; 核心政策 &#x1f6e1;️ VMware Tanzu 开源支持政策 Spring Boot 针对关键错误和安全问题提供支持 &#x1f4c6; 版本支持周期 1️⃣ 主要版本&a…

WeakAuras Lua Script TOC BOSS2 <Lord Jaraxxus>

WeakAuras Lua脚本&#xff08;WA 字符串&#xff09; 十字军试炼老2 加拉克苏斯 血肉成灰 !WA:2!TIv7VnYrz8UXuDudiDN7PqFfCdTHKYLOeN7sBpXvKDIZf36Kyw7KRT3DYE2Dh7DAwV7CZSoXUOIewf4GdAfgbu13LPasv8MS4diavKoH4RSkIp0phXDT8je5FGYZmZU2oVCqrGLJZUpZZoZZB)EEz1wkr9ewjSU6MD5u…

Spring security详细上手教学(二)用户管理

Spring security详细上手教学&#xff08;二&#xff09;用户管理 这章节主要学习&#xff1a; 如何使用UserDetails接口描述用户在鉴权流中使用UserDetailsService自定义的UserDetailsService实现自定义的UserDetailsManager实现在鉴权中使用JdbcUserDetialsManager 在Spri…

网络安全厂商F5荣登2025 CRN AI 100榜单,释放AI潜力

近期&#xff0c;网络安全厂商F5凭借其应用交付和安全技术与前沿的人工智能洞察&#xff0c;成功入选“2025 CRN AI 100 榜单”&#xff0c;并跻身“领导者”之列。这一荣誉的获得&#xff0c;彰显了F5在助力企业拥抱人工智能创新的过程中&#xff0c;无需牺牲性能、灵活性或安…

4.RabbitMQ - 延迟消息

RabbitMQ延迟消息 文章目录 RabbitMQ延迟消息一、延迟消息介绍二、实现2.1 死信交换机2.2 延迟消息插件2.3 取消超时订单 一、延迟消息介绍 延迟消息&#xff1a;生产者发送消息时指定一个时间&#xff0c;消费者不会立刻收到消息&#xff0c;而是在指定时间后才收到消息 用户…

5.学习笔记-SpringMVC(P53-P60)

1.响应 &#xff08;1&#xff09;响应页面 &#xff08;2&#xff09;响应数据&#xff08;异步提交&#xff09;&#xff1a;文本数据、json数据 2.REST风格 (1)REST:表现形式状态转换。 (2)传统风格资源描述形式 3.Restful入门案例 5.基于RESTful页面数据…

Golang | 搜索表达式

// (( A | B | C ) & D ) | E & (( F | G ) & H )import "strings"// 实例化一个搜索表达式 func NewTermQuery(field, keyword string) *TermQuery {return &TermQuery{Keyword: &Keyword{Field: field, Word: keyword},} }func (tq *TermQuery…

LangChain构建大模型应用之RAG

RAG(Retrieval-augmented Generation 检索增强生成)是一种结合信息检索与生成模型的技术,通过动态整合外部知识库提升大模型输出的准确性和时效性。其核心思想是在生成答案前,先检索外部知识库中的相关信息作为上下文依据,从而突破传统生成模型的静态知识边界。 为什么我们…

Ubuntu 下 Nginx 1.28.0 源码编译安装与 systemd 管理全流程指南

一、环境与依赖准备 为确保编译顺利&#xff0c;我们首先更新系统并安装必要的编译工具和库&#xff1a; sudo apt update sudo apt install -y build-essential \libpcre3 libpcre3-dev \zlib1g zlib1g-dev \libssl-dev \wgetbuild-essential&#xff1a;提供 gcc、make 等基…

第十二章-PHP文件上传

第十二章-PHP文件上传 一&#xff0c;文件上传原理 一、HTTP协议与文件上传 1. 请求体结构 当表单设置enctype"multipart/form-data"时&#xff0c;浏览器会将表单数据编码为多部分&#xff08;multipart&#xff09;格式。 Boundary分隔符&#xff1a;随机生成的…

CSS元素动画篇:基于当前位置的变换动画(三)

基于当前位置的变换动画&#xff08;三&#xff09; 前言缩放效果类元素动画脉冲动画效果效果预览代码实现 橡皮筋动画效果效果预览代码实现 果冻动画效果效果预览代码实现 欢呼动画效果效果预览代码实现 心跳动画效果效果预览代码实现 结语 前言 CSS元素动画一般分为两种&…

Redis ssd是什么?Redis 内存空间优化的点都有哪些?embstr 和 row、intset、ziplist分别是什么?

Redis SSD 是什么&#xff1f; Redis SSD 通常指 Redis 使用 SSD&#xff08;固态硬盘&#xff09;作为持久化存储介质的场景。虽然 Redis 是内存数据库&#xff08;数据主要驻留内存&#xff09;&#xff0c;但其持久化机制&#xff08;如 RDB 快照和 AOF 日志&#xff09;需…

【蓝桥杯】 数字诗意

数字诗意 在诗人的眼中&#xff0c;数字是生活的韵律&#xff0c;也是诗意的表达。 小蓝&#xff0c;当代顶级诗人与数学家&#xff0c;被赋予了”数学诗人”的美誉。他擅长将冰冷的数字与抽象的诗意相融合&#xff0c;并用优雅的文字将数学之美展现于纸上。 某日&#xff0…

DHCP 服务器运行流程图

以常见的 DHCP v4 为例,其完整流程如下: 一、客户端请求 IP 地址阶段 DHCPDiscover:客户端启动后,会以广播的形式发送 DHCPDiscover 报文,目的是在网络中寻找可用的 DHCP 服务器。该报文中包含客户端的 MAC 地址等信息,以便服务器能够识别客户端。DHCPOffer:网络中的 D…

一种企业信息查询系统设计和实现:xujian.tech/cs

一种企业信息查询系统设计和实现&#xff1a;xujian.tech/cs 背景与定位 企业在对外合作、风控审查或市场调研时&#xff0c;常需快速获取公开的工商信息。本文介绍一个企业信息搜索引擎&#xff0c;面向普通用户与开发者&#xff0c;帮助快速定位企业名称、统一社会信用代码…

前端面试高频算法

前端面试高频算法 1 排序算法&#xff1b;1.1 如何分析一个排序算法1.1.1 执行效率3.1.2 内存消耗1.1.3 稳定性 1.2 冒泡排序&#xff08;Bubble Sort&#xff09;1.3 插入排序&#xff08;Insertion Sort&#xff09;1.4 选择排序&#xff08;Selection Sort&#xff09;1.5 归…

C++初阶-模板初阶

目录 1.泛型编程 2.函数模板 2.1函数模板概念 2.2实现函数模板 2.3模板的原理 2.4函数模板的实例化 2.4.1隐式实例化 2.4.2显式初始化 2.5模板参数的匹配原则 3.类模板 3.1类模板定义格式 3.2类模板的实例化 4.总结 1.泛型编程 对广泛的类型法写代码&#xff0c;我…

「Mac畅玩AIGC与多模态02」部署篇01 - 在 Mac 上部署 Ollama + Open WebUI

一、概述 本篇介绍如何在 macOS 环境下本地部署 Ollama 推理服务,并通过 Open WebUI 实现可视化交互界面。该流程无需 CUDA 或专用驱动,适用于 M 系列或 Intel 芯片的 Mac,便于快速测试本地大语言模型能力。 二、部署流程 1. 环境准备 安装 Homebrew(如尚未安装):/bin…

JavaScript 中 undefined 和 not defined 的区别

在 JavaScript 的调试过程中&#xff0c;你是否经常看到 undefined 却不知其来源&#xff1f;是否曾被 ReferenceError: xxx is not defined 的错误提示困扰&#xff1f;这两个看似相似的概念&#xff0c;实际上是 JavaScript 类型系统中最重要的分水岭。本文将带你拨开迷雾&am…