『 Linux 』网络传输层 - TCP (一)

文章目录

    • TCP协议
    • TCP数据段格式
    • TCP确认应答机制
    • TCP流量控制

TCP协议

TCP协议(Transmission Control Protocol , 传输控制协议) 是互联网协议套件中的核心协议之一;

主要用于确保数据在网络上的可靠传输,其具有以下特点:

  • 面向连接

    在数据传输前,TCP需要在通信双方之间建立一个连接,这个连接需要通过三次握手来完成从而保证两端的通信准备就绪;

  • 可靠传输

    TCP提供可靠的数据传输服务,确保数据包能够按照顺序且无差错的送达目标;

    其中包括错误检测,重传机制,确认应答等手段来保证数据的完整性和正确传输;

  • 流量控制

    TCP实现流量控制,通过滑动窗口机制确保发送方不会以超过接收方处理能力的速度发送数据从而避免网络拥塞;

  • 拥塞控制

    TCP通过各种算法来检测和应对网络拥塞,调整发送速度,优化网络资源使用;

  • 数据序列化和重组

    发送方将数据流分割成多个数据段发送,在接收方将这些数据段按照顺序重新组装成完整的数据流以保障数据顺序的正确;

  • 全双工

    TCP支持全双工通信,即通信双方可以同时进行数据的发送和接收以提高通信效率;

  • 端口和多路复用

    TCP使用端口号来标示不同的应用程序,并通过多路复用技术支持多个应用程序在同一物理链路上进行传输;

TCP是一种传输控制协议,其中该协议最主要的特点在于 “控制” ,与UDP协议不同,TCP协议具有两个缓冲区,即输入缓冲区与输出缓冲区;

当执行流在使用TCP协议进行数据发送时所调用的sendto本质上是一个拷贝函数,这个函数将数据由应用层协议缓冲区拷贝至传输层协议的缓冲区,当TCP协议识别到缓冲区存在数据时将自行判断数据是否发送以及发送,同时TCP协议也将自行解决如丢包,数据不完整等问题,故被称为控制协议;

TCP的缓冲区是一种内存级缓冲区,与用户或者应用层在数据整合时或者接收传输层上来的数据的缓冲区是不同的;

同时TCP也具有接受缓冲区,这个接收缓冲区和UDP的接收缓冲区同理,在此不做赘述;


TCP数据段格式

TCP数据段格式包含以下内容:

  • 16位源端口号

    发送方的端口号;

  • 16位目标端口号

    接收方的端口号;

  • 32位序号

    标示该段中数据的第一个字节在整个数据流的位置;

  • 32位确认序号

    用于确认接收到的数据,是期望接收下一个字节的序号;

  • 4位首部长度

    自描述字段,指定TCP头部的长度,单位是32位(4Byte);

  • 6位保留字段

    保留供将来使用,目前设置为0;

  • 控制标志

    包括URG,ACK,PSH,RST,SYN,FIN等,用于控制数据流和连接管理;

  • 16位窗口大小

    表示接收方当前可以接收的数据量,用于流量控制;

  • 16位校验和

    检测数据段头部和数据是否有错误;

  • 16位紧急指针

    指示紧急数据的末尾,用于加快处理紧急数据;

  • 选项

    可选字段,例如最大报文段长度(MSS),时间戳等;

  • 数据

    实际传输的数据部分;

当接收方接收到一个TCP报文后需要对报文进行报头和有效载荷的分离以及将分离后的数据交付给上层;

对于TCP协议的报头而言其也是以定长报头从而更好的进行报头和有效载荷的分离;

通常情况下TCP协议的报头定长为20byte,但TCP报文与UDP报文不同,UDP报文的格式为定长报头后紧跟正文数据,而TCP协议在报头与正文数据中夹杂着一层 “选项” ,TCP对报头与有效载荷的分离工作变成了:

  • TCP如何将报头(标准报头与选项)和有效载荷进行分离?

虽然TCP的报文中出现了选项字段,但是在TCP的报头中存在一个 “4位首部长度” 的字段用于更好的将报头与有效载荷进行分离;

“4位首部长度” 记录的是TCP标准报头与选项的总大小,其有四位,取值范围即为 [0-15],其单位为32bit(4字节),即整个TCP报头的大小为0~60byte;

当接收方接收到了一个TCP报文后将会对应的读取其首部长度,通过首部长度来计算出TCP报头的总大小,通过总大小减去定长报头(TCP标准报头)的大小后剩下的则为选项所占大小,计算完报头总体大小后即可对报头与有效载荷进行分离;

当报头与有效载荷分离后需要将报文交付给上层,在TCP报头中存在 “16位目标端口号” 字段,一个端口号只能被一个进程所绑定,所以TCP协议可以精准的将有效载荷部分通过该字段精准交付给上层对应的进程;

与UDP相同,TCP的报头也是以结构化的形式所存在;

同时,无论是请求还是响应,无论数据是否完整,使用TCP协议发送与接收的报文都是一个完整的TCP报文,即该TCP数据段必须包含完整的TCP报头;


TCP确认应答机制

在使用TCP协议进行网络通信时,当客户端发送给服务端发送一次字节流时,服务端必须对该字节流进行响应,否则客户端无法知道最近一次对服务端发送的字节流是否有到达;

同样的,当服务端对客户端发送一段数据段后,对应的客户端也需要对该次字节流进行一次应答;

通过确认应答机制可以保证发送方向接收方数据发送时的可靠性,这个可靠性是相互的,即在每次会话当中必然存在一个发送方与一个接收方(无论是客户端还是服务器);

同时这里的发送方所发送的数据还是接收方所返回的应答都是一个TCP数据段,无论其是否包含数据,该数据段都是一个完整的TCP报文(必定携带TCP报头);

对于应用层协议而言,分为主从概念,即存在客户端也存在服务端,而传输层中的协议,无论是发送方还是接收方其低位是对等的,在传输层进行的网络通信任何一方都会成为发送方同时也会扮演接收方的角色;

而在确认应答机制中可能会存在一个 鸡生蛋蛋生鸡 的问题,即A端向B端发送字节流,B端回复A端字节流使A端明白刚刚所发的字节流已经被接收,那么B端又如何证明该回复的字节流被A端所接收,A端是否需要对该回复字节流再次进行一次应答?

无论通信双方如何进行通信,在最后一条应答字节流后是没有应答的,这也意味着TCP协议尽管尽力提供可靠的通信连接,但也无法保证100%的可靠;

实际上TCP协议并不保证全局通信中的可靠性,只有当一条字节流发送给对端,并且对端对该字节流进行了应答才能保证最新的字节流(应答字节流),之前的字节流是可靠的;

而实际TCP协议在设计过程中也考虑到了这一点,所以在实际通信过程中, 发送方无需对应答再作应答 ;

假设存在两个端分别为A端与B端,每个端既是发送方也是接收方,那么通信过程中保证可靠传输将会有以下两种情况:

  • A端向B端发送数据,B端应答,保证A端到B端数据传输可靠性
  • B端向A端发送数据,A端应答,保证B端到A端数据传输可靠性

而实际上不考虑第一条与最后一条的字节流通信,实际上在中间过程中的字节流传输既可以被看作是数据传输,也可以看作是应答;

只有当一端向另一端发送字节流并且另一端为该字节流进行应答了该端才会知道对端已经接收到了字节流,否则则无法确认该字节流是否被传达,为了保证数据传输的可靠性,TCP协议制定了一个定时任务,即当一条字节流被发送出去后一段时间没有接收到应答则会判定为数据丢失,将重新发送该数据段,即 “超时重传” ;

在上述的网络通信过程中采用的是串行的方式,即双端在接收到对方的应答再发送下一条字节流,而实际上串行的网络通信的过程与效率十分低下;

通常情况下TCP协议所采用的通信方式是一端向另一端发送字节流时为多条字节流并行发送,当对端接收到对应的字节流后只需要对每条字节流进行应答即可;

假设存在两端,A端与B端,当A端向B端以并行的方式发送多条字节流,B端对A端进行逐条字节流的应答,但在网络通信过程中没有百分百的可靠传输,即并行发送的多条字节流可能因为网络拥塞等情况将会出现多条字节流乱序的情况,即 “数据包乱序” ,这种情况会导致数据段由传输层交付给应用层时出现解析出乱序的数据报从而导致无法正确识别对应的正确数据,而数据包乱序本质上就是不可靠的一种体现;

为了避免对端因为数据段乱序导致无法正确识别整理报文,TCP协议制定了一个这样的规则,通过报头中的某个字段对多个数据段进行排序,即 “序号与确认序号” ,通过序号来保证数据的 “按序到达” ;

  • 32位序号

    序号是用于标示数据流中每个字节的位置,具体来说,TCP将数据视为一个连续的字节流,每个字节都有一个唯一的序列号;

    序列号用于标示每个字节的位置确保数据按顺序传输和重组;

    在TCP建立连接时双方都将随机选择一个序列号,通常情况下在建立连接的三次握手中会协商这些数据,随机选择是为了保证安全性;

    对于后续的序列号将会根据数据段的数量对序列号进行递增,如果初始序列号是1000,发送了500字节的数据,下一字节的序列号将是1500,这也将根据窗口大小动态进行调整;

    同时为了保证TCP报文不会因为序号而超过报头的固定长度,在一定长度后序号将会进行回滚,通常情况下当序号到达4,294,967,295,即32位满,对应序列号将会回滚为0,由0开始计算,除该情况外,TCP报头的序号是伴随整个连接的数据发送递增的(对单独一端而言);

  • 32位确认序号

    确认序号既表示告诉对端在该确认序号之前的所有字节流已经被进行接收的应答,也是期望对端下一序列号的开始位置,通常为向后偏移一个字节;

    由于序列号的实际范围为 “序列号 + 报文有效载荷长度 - 1” , 对于确认序号而言,其所填充的数据是所接收的数据流的 “序列号 + 报文有效载荷长度” ;

    这是一种协议上的约定,在TCP网络通信过程中可能会因为网络拥塞或是其他问题导致的数据丢失问题,但依靠这种约定对端可以明确知道在该确认序号前的所有序号的数据流已经被接收;

    即一个确认序号可以代表多条数据流的应答;

    一端在对另一端发送数据流时本质上也是对对端上一所发数据流的应答,但是在应答当中可能出现不存在有效载荷的情况,即没有有效正文数据,此时对应的确认应答即能成为对对端上一所发数据的应答;

序号和确认序号可能同时存在,尤其是在双向通信过程中;

同时因为确认序号的存在,TCP协议在进行网络通信过程中允许少部分的应答丢失;


TCP流量控制

TCP协议是一种提供可靠传输服务的协议,其中可靠传输包含了防止丢包的问题;

对于丢包的问题有很多,包括网络传输过程中丢包,发送方的发送速度大于接收方处理TCP报文的处理能力导致的丢包,但无论是哪种丢包TCP协议都能通过重传,超时重传,快速重传等策略为TCP的数据传输提供可靠性;

但对于发送端与接收方处理能力不匹配的情况,如果出现大量的丢包情况则可能降低双方的效率,尤其是对于发送方而言,接收方无法快速处理来自发送方所发来的TCP数据段从而导致接收缓冲区溢出,则每次新的从发送方发来的TCP数据段都将可能被丢弃,导致发送方为了保持数据传输的可靠性而不停重传,大大降低了发送端的效率;

在这种情况下,发送方无法确认数据段为什么会丢包,但以发送方的视角而言该次丢包就是不可靠的,所以为保证数据传输可靠性发送方将不停重发,直至接收方将接收缓冲区中的数据段处理了一些以有足够的空间来容纳本次来自发送端的数据段;

而TCP协议是一种保证可靠性的传输方式,其自身使用对应的策略来应对这种问题的发生从而避免因为双方处理能力不兼容从而导致大面积丢包情况;

通常采用匹配双方处理能力从而使得接收方不会因为发送方所发送的数据段过多导致就接收缓冲区溢出从而引起的大面积丢包,这种策略被称为流量控制;

对发送方而言,发送速度需要由对方的接收缓冲区中所剩余的空间大小来决定,同时TCP协议是基于确认应答机制的;

在TCP报头中存在字段 “16位窗口大小” , 该字段就是标明本端中的窗口大小,即告诉对端本端所期望的下次接收数据的大小,这个窗口大小是一个约定值(约定下次所发的数据不超过该大小),当一端向另一段返回对应的数据段时报头中将携带这一字段,对端再次发送数据段时只需发送不超过该窗口大小的数据量即可;

窗口大小是通信过程中一个动态的字段,本端将会根据自己的处理能力以及当前接收缓冲区的剩余空间来重新规划窗口大小,即 “滑动窗口” ;

通常在一次连接当中都将使用 “慢启动” 的方式来设置窗口大小从而匹配双端的处理速度;

  • 慢启动

    从一个较小的窗口大小开始传输数据,并逐步增大窗口大小,以此适应网络的实际容量;

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

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

相关文章

MySQL的group_concat函数:将分组中的多个值连接成一个字符串的聚合函数

MySQL的group_concat函数:将分组中的多个值连接成一个字符串的聚合函数 主要作用说人话解释举个🌰 主要作用 可以将同一组内的多个值合并为一个由指定分隔符分隔的字符串,简化数据展示和分析。 说人话解释 group_concat()会计算哪些行属于…

怎么找歌曲的伴奏?找伴奏不再难

在音乐创作、演唱练习或是娱乐活动中,找到一首歌曲的伴奏版本是一个常见的需求。伴奏不仅能够帮助我们更好地理解歌曲的结构和旋律,还能为演唱者提供一个专业的音乐背景。那么,我们该如何有效地找到歌曲的伴奏呢?本文将为你提供几种实用的方…

ubuntu18.04安装xenomai3.1(百分百成功版)

准备工作 1、下载ubuntu18.04.06。 https://releases.ubuntu.com/18.04/ubuntu-18.04.6-desktop-amd64.iso 2、安装虚拟机vmware或virtual machine。 开始安装xenomai 1、在桌面安装一个文件夹,文件夹名字叫xenomai。 2、 在终端输入uname-a 查看自己的内核版本。 3、下…

Linux学习笔记 | sudo命令的基本使用

sudo命令 sudo 命令是 Unix 和 Linux 系统中用于执行需要超级用户权限(即 root 权限)操作的工具。它允许系统管理员授予某些用户(或用户组)以 root 或其他指定用户的权限来运行特定命令,而无需知道 root 用户的密码。…

电脑怎么进行全盘加密?

1.使用Windows自带的BitLocker: 打开“控制面板”,选择“系统和安全”,然后点击“BitLocker驱动器加密”。 选择要加密的驱动器,点击“启用BitLocker”。 选择解锁驱动器的方式,通常选择“使用密码解锁驱动器”&…

内盘期货配资牛/文华财经有资管软件吗

文华财经不仅提供行情、交易、资讯于一体的综合性期货交易软件,还针对投资者的资产管理需求,开发了一系列功能强大的资管软件。这些软件的核心功能包括实时行情监控、技术分析工具、交易执行系统以及风险管理模块,全方位满足了期货配资投资者…

Python 函数返回值之None类型

什么是None None是类型‘NoneType’字面量,用于表示:空的、无意义的 函数如何返回None 不使用return语句即返回None 主动return None 使用场景 函数返回值if判断变量定义 练习: 练习一:无return语句的函数返回值 # 无ret…

自动发现-实现运维管理自动化

nVisual-Discovery是一款自动化工具软件,通过多种自动发现技术,协助运维管理人员快速建立可视化的网络文档,提升网络管理的效率与准确性。 01 IP扫描发现 当我们新接手一个网络运维项目,通常缺乏精准的网络文档数据,…

uniapp 引入了uview-ui后,打包错误,主包过大解决方案

原因:由于使用uniapp来设计小程序,使用uview的组件库,导致了主包过大,无法打包 前提条件:已经完成了分包,如果还没有分包的先分包,需要上传代码时用到 1. 通常情况,大多数都是通过点…

Oracle SQL Developer 同时打开多个table的设置

Oracle SQL Developer 同时打开多个table的设置 工具 》 首选项 》数据库 》对象查看器,勾选 “自动冻结对象查看器窗口”

面试题:JVM(一)

1. JVM概述 1.1 JVM的生命周期 说说Java虚拟机的生命周期(阿里) 虚拟机的启动 Java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的。 虚拟机的退出有如下…

javaScript整数反转

function _reverse(number) { // 补全代码 return (number ).split().reverse().join(); } number :首先,将数字 number 转换为字符串。在 JavaScript 中,当你将一个数字与一个字符串相加时,JavaScript 会自动将数字转换为字符串…

基于SpringBoot的“高校校园点餐系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“高校校园点餐系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 前台首页功能界面图 用户注册、登录界面图 我…

unity游戏开发之塔防游戏

如何制作塔防游戏 让我们以迷你游戏的形式创建一个休闲塔防。 从基本处理到适用技术,应有尽有,因此您只需制作一次即可获得 Unity 中的游戏制作专业知识。 与背景素材结合使用时,您将获得以下游戏视图: 由于在创建过程中使用了 …

Google DeepMind的研究人员提出了Talker-Reasoner框架

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

【复旦微FM33 MCU 外设开发指南】外设篇1——硬件除法器

前言 本系列基于复旦微FM33LC0系列单片机的DataSheet编写,旨在提供一些开发指南。 本文章及本系列其他文章将持续更新,本系列其它文章请跳转【复旦微FM33 MCU 外设开发指南】总集篇 本文章最后更新日期:2024/10/24 文章目录 前言用途工作流…

若依 spring boot +vue3 前后端分离

若依方便之处 如果你需要一个前后端分离管理web系统,可以通过若依快速搭建一个基于spring boot vue的管理系统,当然还有cloud版,和App移动版可供选择,本文搭建的是spring boot vue3.x版本 若依官网 https://www.ruoyi.vip/ 环境…

贪心算法day(1)

1.将数组和减半的最少操作次数 链接:. - 力扣(LeetCode) 思路:创建大跟堆将最大的数进行减半 注意点:double t queue.poll()会将queue队列数字减少一个后再除以2,queue.offer(queue.poll()/…

第十三部分 Java IO

第十三部分 Java IO 13.1 IO概述 13.1.1 什么是IO 生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了ctrls ,可能文件就白白编辑了。当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数…

EfficientNet-B6模型实现ISIC皮肤镜图像数据集分类

项目源码获取方式见文章末尾! 回复暗号:13,免费获取600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于opencv答题卡识别判卷】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【G…