【Linux网络】网络基础:传输层TCP协议(二)

news2025/4/17 11:21:23

📝个人主页🌹:Eternity._
⏩收录专栏⏪:Linux “ 登神长阶 ”
🌹🌹期待您的关注 🌹🌹

在这里插入图片描述

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

❀ 传输层UDP/TCP协议

  • 确认应答机制
  • 超时重传机制
  • 连接管理机制
    • 理解 TIME_WAIT 状态
  • 滑动窗口
  • 流量控制
  • 拥塞控制
  • 延迟应答
  • 捎带应答
  • 粘包问题
  • 总结

前言:在当今这个信息爆炸、网络互联的时代,TCP(Transmission Control Protocol,传输控制协议)作为互联网通信的基石之一,扮演着举足轻重的角色。无论是我们日常浏览网页、观看在线视频,还是企业进行大规模数据传输、云计算服务,TCP协议都默默地在幕后工作,确保数据的可靠、有序和高效传输。

TCP协议自1974年由Vint Cerf和Bob Kahn提出以来,经历了无数次的迭代与优化,逐渐成为互联网中最广泛使用的传输层协议之一。它不仅仅是一种技术规范,更是一种智慧的结晶,体现了人类对复杂网络通信需求的深刻理解和精妙设计。

然而,TCP协议机制的复杂性和多样性,常常让初学者感到困惑和迷茫。它涵盖了从三次握手建立连接、滑动窗口流量控制、拥塞控制算法,到数据包的拆分与重组、错误检测与重传等多个方面,每一个细节都蕴含着深刻的原理和实践经验。

让我们一同踏上探索TCP协议机制的旅程,共同领略这一伟大发明的魅力与智慧。

确认应答机制


我们上一篇用寄快递的抽象例子简单介绍了一下确认应答机制:

在这里插入图片描述
TCP会给我们发送的每个数据进行编号,也就是序列号

在这里插入图片描述

每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据,下一次你从哪里开始发。

超时重传机制


  • 当我们主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B
  • 如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发

在这里插入图片描述
当然了除了上面这种情况外,主机A未收到B发来的确认应答,还有可能是发送回来的ACK丢了

在这里插入图片描述
因此主机B会收到很多重复数据,那么TCP协议需要能够识别出那些包是重复的包,并且把重复的丢弃掉,这时候我们可以利用前面提到的序列号达到去重的效果。

超时时间的设置:

  • 找到一个最小的时间, 保证 “确认应答一定能在这个时间内返回”
  • 时间会随着网络环境的不同,会有所不同
  • 如果超时时间设的太长,会影响整体的重传效率
  • 如果超时时间设的太短,有可能会频繁发送重复的包

TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间

  • Linux中(BSD Unix和Windows也是如此),超时以500ms为一个单位进行控制, 每次判定超时重发的超时时间都是500ms的整数倍
  • 如果重发一次之后,仍然得不到应答,等待 2*500ms 后再进行重传
  • 如果仍然得不到应答, 等待 4*500ms 进行重传,依次类推,以指数形式递增
  • 累计到一定的重传次数,TCP认为网络或者对端主机出现异常,强制关闭连接

注意:

  • 发送方一旦把数据发出去,一段时间内已经发送的数据是会被暂时保存起来的,然后根据具体情况决定它的去留
  • 暂时保存的数据在发送缓冲区的滑动窗口中,收到应答的时候,通过窗口滑动,删除指定的报文

连接管理机制


在正常情况下, TCP要经过三次握手建立连接,四次挥手断开连接
在这里插入图片描述

在这里插入图片描述

为什么要进行三次握手:

  • 如果只进行一次或者两次握手,此时有客户端恶意挂靠链接,就会造成SYN洪水问题
    1. 最小成本验证TCP全双工
    1. 基数次握手,客户端优先将链接建立好,服务器才建立,此时客户端要承担对等的成本来建立连接,有效防止了客户端恶意挂靠链接
    1. 新的角度看待三次握手:4次握手 + 捎带应答

在这里插入图片描述


在这里插入图片描述
当我们在进行断开连接时,是需要经历许多状态的

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

连接断开后,会维持一段时间的TIME_WAIT状态,在此期间, 不能重新在同样的端口启动服务,虽然server的应用程序终止了,但TCP协议层的连接并没有完全断开,因此不能再次监 听同样的server端口

理解 TIME_WAIT 状态


  • TCP协议规定,主动关闭连接的一方要处于TIME_ WAIT状态,等待两个MSL(maximum segment lifetime)的时间后才能回到CLOSED状态
  • 我们使用Ctrl-C终止了server,所以server是主动关闭连接的一方,在TIME_WAIT期间仍然不能再次监听同样的server端口
  • MSL在RFC1122中规定为两分钟,但是各操作系统的实现不同,在Centos7上默认配置的值是60s
  • 可以通过 cat /proc/sys/net/ipv4/tcp_fin_timeout 查看msl的值

网络中可能还会存在尚未到达的报文,TIME_WAIT存在的原因就是让历史报文从网络中消散。

在这里插入图片描述

为什么是TIME_WAIT的时间是2MSL:

  • MSL是TCP报文的最大生存时间,因此TIME_WAIT持续存在2MSL的话就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失(否则服务器立刻重启,可能会收到来自上一个进程的迟到的数据,但是这种数据很可能是错误的)
  • 同时也是在理论上保证最后一个报文可靠到达(假设最后一个ACK丢失,那么服务器会再重发一个FIN。这时虽然客户端的进程不在了,但是TCP连接还在,仍然可以重发LAST_ACK);

有时我们在终止一个连接,马上用同一个端口号再次连接时,就会出现问题,这就是由于TIME_WAIT状态,引起的bind失败。端口号和TIME_WAIT占用的链接重复了

  • 使用setsockopt()设置socket描述符的 选项SO_REUSEADDR为1, 表示允许创建端口号相同但IP地址不同的多个socket描述符
    在这里插入图片描述

滑动窗口


服务器对每一个客户端发送的数据段,都要一一给予ACK确认应答,收到ACK后再发送下一个数据段。这样做效率非常地下,尤其是数据往返的时间较长的时候,因此TCP肯定有一次性发送多条数据的方法(多个段的等待时间重叠)

在这里插入图片描述

  • 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值,上图的窗口大小就是4000个字节(四个段)
  • 发送前四个段的时候,不需要等待任何ACK, 直接发送
  • 收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据,依次类推
  • 操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区 来记录当前还有哪些数据没有应答,只有确认应答过的数据,才能从缓冲区删掉
  • 窗口越大,则网络的吞吐率就越高

在这里插入图片描述

在这里插入图片描述
当我们在发送数据时,接收方在缓冲区在写入数据时,上层没有将数据取走,随着时间的推移,窗口大小会慢慢变小,左侧慢慢在滑动,右侧一直不滑动。既然可以变小,当然可以变为0,也可以变大。

滑动窗口的发送缓冲区类似于环形结构,不用考虑越界问题

在这里插入图片描述

流量控制


接收端处理数据的速度是有限的,如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。因此TCP支持根据接收端的处理能力,来决定发送端的发送速度,这个机制就叫做流量控制(Flow Control)

  • 接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段,通过ACK端通知发送端
  • 窗口大小字段越大,说明网络的吞吐量越高
  • 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端
  • 发送端接受到这个窗口之后,就会减慢自己的发送速度;
  • 如果接收端缓冲区满了,就会将窗口置为0,这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端

在这里插入图片描述

在TCP三次握手时, 收发双方就会交换各自的接受缓冲区,知道对方接受能力

拥塞控制


TCP虽然有滑动窗口,能够高效可靠的发送大量的数据,但是如果在网络状态比较拥堵时,开始阶段就发送大量的数据,仍然可能引发问题。

在不清楚当前网络状态下,贸然发送大量的数据,可能损失惨重,发生大面积丢包,发送方可能会判定网络出现问题,让大量数据进行重传,数据大量堆积进而造成网络瘫痪,TCP引入 慢启动 机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据 这就是 TCP 的拥塞控制

在这里插入图片描述

  • 此处引入一个概念程为拥塞窗口
  • 发送开始的时候,定义拥塞窗口大小为1
  • 每次收到一个ACK应答,拥塞窗口加1
  • 在每次发送数据包时,网络良好则考虑对方接受能力,如对方接受能力强则考虑网络问题
  • 每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小的值作为实际发送的窗口

在这里插入图片描述

拥塞窗口增长速度, 是指数级别的( 2 n 2^n 2n)。“慢启动” 只是指初使时慢, 但是增长速度非常快

  • 为了不增长的那么快,因此不能使拥塞窗口单纯的加倍
  • 此处引入一个叫做慢启动的阈值
  • 当拥塞窗口超过这个阈值的时候,不再按照指数方式增长,而是按照线性方式增长

在这里插入图片描述

  • 当TCP开始启动的时候,慢启动阈值等于窗口最大值
  • 在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置回1
  • 少量的丢包,我们仅仅是触发超时重传,大量的丢包,我们就认为网络拥塞
  • 当TCP通信开始后,网络吞吐量会逐渐上升,随着网络发生拥堵,吞吐量会立刻下降
  • 拥塞控制归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力

延迟应答


如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小:

  • 假设接收端缓冲区为1M。一次收到了500K的数据,如果立刻应答,返回的窗口就是500K
  • 但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了
  • 接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来
  • 如果接收端稍微等一会再应答,等待200ms再应答,那么这个时候返回的窗口大小就是1M
    在这里插入图片描述

窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率

延迟应答也许满足相应条件:

  • 数量限制:每隔N个包就应答一次
  • 时间限制:超过最大延迟时间就应答一次
  • 具体的数量和超时时间,依操作系统不同也有差异,一般N取2,超时时间取200ms,如果超过可能误判重传

捎带应答


很多情况下,客户端服务器在应用层也是 “一发一收” 的。意味着客户端给服务器说了 “How are you”,服务器也会给客户端回一个 “Fine, thank you”,那么这个时候ACK就可以搭顺风车,和服务器回应的 “Fine, thank you” 一起回给客户端。我们在三次握手中,就应用到了捎带应答

在这里插入图片描述

粘包问题


我们在做包子的时候,当它刚蒸好出锅的时候,我们用手去拿的时候,一下子可能会拿起来很多个,它们的边界是连在一起的,所以我们在包子刚出锅的时候,是先要把它们一个一个分开的。

  • 粘包问题中的 “包” ,是指的应用层的数据包
  • 在TCP的协议头中,没有如同UDP一样的 “报文长度” 这样的字段,但是有一个序号这样的字段
  • 站在传输层的角度,TCP是一个一个报文过来的,按照序号排好序放在缓冲区中
  • 站在应用层的角度,看到的只是一串连续的字节数据
  • 那么应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始到哪个部分,是一个完整的应用层数据包

如何避免粘包问题,首要的就是明确两个包之间的边界:

  • 对于定长的包,保证每次都按固定大小读取即可,例如上面的Request结构,是固定大小的,那么就从缓冲区从头开始按sizeof(Request)依次读取即可
  • 对于变长的包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置
  • 对于变长的包,还可以在包和包之间使用明确的分隔符

对于UDP协议来说, 不会存在 "粘包问题"

总结


TCP异常情况:

  • 进程终止: 进程终止会释放文件描述符,仍然可以发送FIN,和正常关闭没有什么区别
  • 机器重启: 和进程终止的情况相同
  • 机器掉电/网线断开: 接收端认为连接还在,一旦接收端有写入操作,接收端发现连接已经不在了,就会进行reset。期询问对方是否还在即使没有写入操作,如果对方不在,TCP自己也内置了一个保活定时器,也会把连接释放

TCP之所以复杂,是因为要保证可靠性, 同时又尽可能的提高性能

可靠性:

  • 校验和
  • 序列号(按序到达)
  • 确认应答
  • 超时重发
  • 连接管理
  • 流量控制
  • 拥塞控制

提高性能:

  • 滑动窗口
  • 快速重传
  • 延迟应答
  • 捎带应答

其他:

  • 定时器(超时重传定时器, 保活定时器, TIME_WAIT定时器等)

在探索TCP(传输控制协议)这一互联网通信基石的征途中,我们不仅揭开了其复杂而精细机制的神秘面纱,更深刻理解了为何TCP能够成为现代网络通信中不可或缺的一部分。TCP以其可靠的数据传输、流量控制、拥塞避免以及错误检测与恢复等特性,构建了一个既稳健又高效的数据传输框架,确保了数据从源头到目的地的无缝流动,即便是在面对复杂多变的网络环境时亦能游刃有余。

通过本文的梳理, 我们从TCP的三次握手建立连接,到数据传输过程中的序列号与确认应答机制,再到滑动窗口实现的流量控制,以及慢启动、拥塞避免等策略,一步步揭示了TCP协议背后的智慧与精妙。 这些机制不仅仅是技术上的创新,更是人类智慧在解决复杂通信问题上的集中体现,它们共同构成了TCP强大的错误恢复能力和网络适应能力。

让我们带着这份启示,继续在技术的海洋中遨游,为构建更加智能、高效、安全的网络世界贡献自己的力量。

在这里插入图片描述

希望本文能够为你提供有益的参考和启示,让我们一起在编程的道路上不断前行!
谢谢大家支持本篇到这里就结束了,祝大家天天开心!

在这里插入图片描述

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

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

相关文章

virtualbox 搭建ubuntu

环境:VirtualBox-6.1.32 1、下载安装virtualbox 略 2、新建ubuntu 3、配置ubuntu 选择虚拟盘 4、安装ubuntu 5、安装ssh sudo apt install openssh-server openssh-client 查看ip 6、安装samba sudo apt install samba 查看ssh启动状态 sudo systemctl stat…

智能人体安全防护:3D 视觉技术原理、系统架构与代码实现剖析

随着工业化程度的提高,生产安全已成为企业关注的重点。尤其是在一些存在禁区的工业厂区和车间,人员误入或违规进入将带来严重的安全隐患。为了解决这一问题,迈尔微视推出了智能人体安全检测解决方案,为企业提供全方位的人员安全监…

Javaweb web后端maven介绍作用安装

自动导入到这个项目 src是源代码 main主程序,核心代码 java是Java源代码 resources是项目配置文件 test测试相关的 maven概述 介绍 依赖在本地仓库查找,如果本地仓库有,用本地仓库的依赖,本地没有,连接中央仓库&…

独家原创 | CEEMDAN-CNN-GRU-GlobalAttention + XGBoost组合预测

往期精彩内容: 时序预测:LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较 全是干货 | 数据集、学习资料、建模资源分享! EMD变体分解效果最好算法——CEEMDAN(五)-CSDN博客 拒绝信息泄露!VMD滚动分…

网络基础概念

协议 协议在我的理解看来其实就是为了让全部计算机做通信而设计出来的一种约定 计算机之间的传输媒介是光信号和电信号. 通过 "频率" 和 "强弱" 来表示 0 和 1 这样的信息. 要想传递各种不同的信息, 就需要约定好双方的数据格式 而制定协议这件事情并不是…

向量数据库Faiss C++

目录 1. Faiss简介2. FAISS 的主要特点2.1 高效性2.2 支持多种索引类型2.3 灵活性2.4 GPU 加速2.5 易于集成 3. 应用场景4. 安装4.1 安装依赖4.2 编译源码4.2.1 下载Faiss源码4.2.2 编译 5. Demo5.1 代码5.2 编译5.3 运行 1. Faiss简介 FAISS(Facebook AI Similari…

群控系统服务端开发模式-应用开发-获取登录者今天操作日志

一、后端api开放路由 在根目录下route文件夹下app.php文件中,在perimission的group中添加如下代码: Route::get(member/personal_log,permission.Member/personalLog);// 获取个人信息操作接口 二、后端api添加方法 在根目录下app文件夹下controller文…

淘宝/天猫获得淘宝商品详情高级版 API 接口获取

要获取淘宝/天猫商品详情高级版API接口,您可以按照以下步骤操作: 注册淘宝开放平台账号: 访问淘宝开放平台官网,点击“开发者中心”,使用淘宝账号登录或注册新账号。这是获取API权限和密钥的第一步。 创建应用并获取AP…

腾讯云系统盘扩容

在腾讯云申请空间后,只要执行三行命令 云硬盘 在线扩展系统盘分区及文件系统-操作指南-文档中心-腾讯云 安装工具 yum install -y cloud-utils-growpart 给/eav/vda1扩分区 LC_ALLen_US.UTF-8 growpart /dev/vda 1 挂载扩容 ext4 文件系统 resize2fs /dev/vda1 …

数据结构 ——二叉树转广义表

数据结构 ——二叉树转广义表 1、树转广义表 如下一棵树&#xff0c;转换为广义表 root(c(a()(b()()))(e(d()())(f()(j(h()())())))) (根&#xff08;左子树&#xff09;&#xff08;右子树&#xff09;) 代码实现 #include<stdio.h> #include<stdlib.h>//保存…

人工智能大语言模型起源篇(二),从通用语言微调到驾驭LLM

上一篇&#xff1a;《人工智能大语言模型起源篇&#xff08;一&#xff09;&#xff0c;从哪里开始》 &#xff08;5&#xff09;Howard 和 Ruder 于2018年发表的《Universal Language Model Fine-tuning for Text Classification》&#xff0c;https://arxiv.org/abs/1801.06…

设置笔记本同时连接内外网

原理&#xff1a;通过笔记本和手机相连&#xff0c;实现双网卡功能能。笔记本连接内网wifi、同时手机端开启usb网络共享&#xff0c;笔记本就有了两个网&#xff0c;然配置那个访问外网&#xff0c;那个访问内网。 1.笔记本wifi连接内网wifi 2.手机端共享网络。 手机打开 -【…

【Hexo】Hexo基本使用

Hexo官网&#xff1a;https://hexo.io/ Hexo Github: https://github.com/hexojs/hexo Hexo Awesome: https://github.com/hexojs/awesome-hexo 1、初始化 需要node 环境&#xff0c;不再赘述node安装过程 推荐使用cnpm进行安装 npm install -g cnpm --registryhttps://regi…

PPO系列4 - Reward模型训练

流程&#xff1a; 训练Reward模型 训练数据&#xff1a; 相比给每条回答进行打分&#xff0c;人类更容易给出两者的比较结果。这样标注出来的数据&#xff0c;准确性更高。 模型&#xff1a; 可以使用和生成模型能力差不多的模型&#xff08;或者更强的模型&#xff09;&#x…

5.11如何用PyTorch实现ResNet34

ResNet34是由16个残差块和一个全局平局池化层和一个全连接层组成&#xff0c;即32个卷积层1个pooling层1和fc层。 训练的数据集是cifar10数据集&#xff0c;训练次数5&#xff0c;损失函数为CrossEntropyLoss()&#xff0c;optimizer torch.optim.SGD。 1.先定义残差块&#…

yolov,coco,voc标记的睡岗检测数据集,可识别在桌子上趴着睡,埋头睡觉,座椅上靠着睡,平躺着睡等多种睡姿的检测,6549张图片

yolov&#xff0c;coco,voc标记的睡岗检测数据集&#xff0c;可识别在桌子上趴着睡&#xff0c;埋头睡觉&#xff0c;座椅上靠着睡&#xff0c;平躺着睡等多种睡姿的检测&#xff0c;6549张图片 数据集分割 6549总图像数 训练组91&#xff05; 5949图片 有效集9&#x…

【C++游记】string的使用和模拟实现

枫の个人主页 你不能改变过去&#xff0c;但你可以改变未来 算法/C/数据结构/C Hello&#xff0c;这里是小枫。C语言与数据结构和算法初阶两个板块都更新完毕&#xff0c;我们继续来学习C的内容呀。C是接近底层有比较经典的语言&#xff0c;因此学习起来注定枯燥无味&#xf…

【深度学习量化交易7】miniQMT快速上手教程案例集——使用xtQuant进行历史数据下载篇

我是Mr.看海&#xff0c;我在尝试用信号处理的知识积累和思考方式做量化交易&#xff0c;应用深度学习和AI实现股票自动交易&#xff0c;目的是实现财务自由~ 目前我正在开发基于miniQMT的量化交易系统。 在前几篇的文章中讲到&#xff0c;我正在开发的看海量化交易系统&#x…

相差不超过k的最多数,最长公共子序列(一),排序子序列,体操队形,青蛙过河

相差不超过k的最多数 链接:相差不超过k的最多数 来源&#xff1a;牛客网 题目描述&#xff1a; 给定一个数组&#xff0c;选择一些数&#xff0c;要求选择的数中任意两数差的绝对值不超过 &#x1d458; 。问最多能选择多少个数&#xff1f; 输入描述: 第一行输入两个正整…

解决navicat 导出excel数字为科学计数法问题

一、原因分析 用程序导出的csv文件&#xff0c;当字段中有比较长的数字字段存在时&#xff0c;在用excel软件查看csv文件时就会变成科学技术法的表现形式。 其实这个问题跟用什么语言导出csv文件没有关系。Excel显示数字时&#xff0c;如果数字大于12位&#xff0c;它会自动转化…