【网络原理】TCP协议详细解析

文章目录

  • 🌲TCP协议的概念
    • 🌸TCP协议段格式
    • 🌸TCP的特性
  • 🌳TCP原理详解
    • 🌸确认应答机制(安全机制)
    • 🌸超时重传机制(安全机制)
    • 🌸连接管理(安全机制)
    • 🌸滑动窗口(效率机制)
    • 🌸流量控制(安全机制)
    • 🌸拥塞控制(安全机制)
    • 🌸延迟应答(效率机制)
    • 🌸捎带应答(效率机制)
  • 🎍面向字节流的粘包问题
    • 🌸思考:
  • 🌴TCP异常情况
  • ⭕TCP小结

🌲TCP协议的概念

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

🌸TCP协议段格式

在这里插入图片描述

  • 源/⽬的端⼝号: 表⽰数据是从哪个进程来, 到哪个进程去
  • 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字节头部选项: 暂时忽略;

🌸TCP的特性

  • TCP提供一种面向连接的, 可靠的字节流服务;

  • 在一个TCP连接中,仅有两方进行彼此通信。广播和多播不能用于TCP;

  • TCP使用校验和, 确认应答和超时重传机制来保证可靠传输;

  • TCP使用累积确认

  • TCP使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制

🌳TCP原理详解

TCP对数据传输提供的管控机制,主要体现在两个方面:安全效率

这些机制和多线程的设计原则类似:保证数据传输安全的前提下,尽可能的提高传输效率

🌸确认应答机制(安全机制)

确认应答机制图示如下
在这里插入图片描述
TCP将每个字节的数据都进⾏了编号. 即为序列号.
在这里插入图片描述
每⼀个ACK都带有对应的确认序列号, 意思是告诉发送者, 我已经收到了哪些数据; 下⼀次你从哪⾥开始发.

🌸超时重传机制(安全机制)

在这里插入图片描述

有了确认应答后,我们的可靠性已经得到大大的提升,但是UDP中出现的丢包问题还是没有得到解决
意思也就是主机A向主机B发送数据,一定时间后,并没有收到应答,这里主机A没有收到应答报文有两种情况

• 主机A发送数据给B之后, 可能因为⽹络拥堵等原因, 数据⽆法到达主机B;
• 如果主机A在⼀个特定时间间隔内没有收到B发来的确认应答, 就会进⾏重发;
但是, 主机A未收到B发来的确认应答, 也可能是因为ACK丢失了;

这两种情况都当成第一种情况处理,客户端会进行重传数据
在这里插入图片描述
因此主机B会收到很多重复数据. 那么TCP协议需要能够识别出那些包是重复的包, 并且把重复的丢弃掉.
这时候我们可以利⽤前⾯提到的序列号, 就可以很容易做到去重的效果.(这里的主机B这里接收就像一个优先级的队列,我们会对传来的数据按照序列号进行排序,如果序列号相同,该队列还可以起到一个去重的效果)

那么, 如果超时的时间如何确定?
• 最理想的情况下, 找到⼀个最⼩的时间, 保证 “确认应答⼀定能在这个时间内返回”.
• 但是这个时间的⻓短, 随着⽹络环境的不同, 是有差异的.
• 如果超时时间设的太⻓, 会影响整体的重传效率;
• 如果超时时间设的太短, 有可能会频繁发送重复的包;

TCP为了保证⽆论在任何环境下都能⽐较⾼性能的通信, 因此会动态计算这个最⼤超时时间.

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

🌸连接管理(安全机制)

由于这里内容较多,博主单独写了一篇进行介绍,大家可以博主写的TCP三次握手四次挥手详解进行学习观看。

🌸滑动窗口(效率机制)

博主在这篇TCP滑动窗口与流量控制和拥塞控制有详细讲解

🌸流量控制(安全机制)

博主在这篇TCP滑动窗口与流量控制和拥塞控制有详细讲解

🌸拥塞控制(安全机制)

博主在这篇TCP滑动窗口与流量控制和拥塞控制有详细讲解

🌸延迟应答(效率机制)

如果接收数据的主机⽴刻返回ACK应答, 这时候返回的窗⼝可能⽐较⼩.

假设接收端缓冲区为1M. ⼀次收到了500K的数据; 如果⽴刻应答, 返回的窗⼝就是500K;
• 但实际上可能处理端处理的速度很快, 10ms之内就把500K数据从缓冲区消费掉了;
• 在这种情况下, 接收端处理还远没有达到⾃⼰的极限, 即使窗⼝再放⼤⼀些, 也能处理过来;
• 如果接收端稍微等⼀会再应答, ⽐如等待200ms再应答, 那么这个时候返回的窗⼝⼤⼩就是1M;

⼀定要记得, 窗⼝越⼤, ⽹络吞吐量就越⼤, 传输效率就越⾼. 我们的⽬标是在保证⽹络不拥塞的情况下
尽量提⾼传输效率;

那么所有的包都可以延迟应答么? 肯定也不是;

• 数量限制: 每隔N个包就应答⼀次;
• 时间限制: 超过最⼤延迟时间就应答⼀次

在这里插入图片描述

🌸捎带应答(效率机制)

在延迟应答的基础上,我们发现,很多情况下,客户端服务器在应用层也是 “一发一收” 的。

意味着客户端给服务器说了 “How are you”,服务器也会给客户端回一个 “Fine, thank you”;

那么这个时候ACK就可以搭顺风车,和服务器回应的 “Fine,thank you” 一起回给客户端
在这里插入图片描述

🎍面向字节流的粘包问题

首先我们需要明确的是

我们在开发中,创建一个TCP的socket,同时在内核中创建一个 发送缓冲区 和一个 接收缓冲区

• 调⽤write时, 数据会先写⼊发送缓冲
• 如果发送的字节数太⻓, 会被拆分成多个TCP的数据包发出;
• 如果发送的字节数太短, 就会先在缓冲区⾥等待, 等到缓冲区⻓度差不多了, 或者其他合适的时机发
送出去;
• 接收数据的时候, 数据也是从⽹卡驱动程序到达内核的接收缓冲区;
• 然后应⽤程序可以调⽤read从接收缓冲区拿数据;
• 另⼀⽅⾯, TCP的⼀个连接, 既有发送缓冲区, 也有接收缓冲区, 那么对于这⼀个连接, 既可以读数据,
也可以写数据. 这个概念叫做 全双⼯

由于缓冲区的存在,TCP程序的读和写不需要一一匹配,例如

  • 写100个字节数据时,可以调用一次write写100个字节,也可以调用100次write,每次写一个字节;
  • 读100个字节数据时,也完全不需要考虑写的时候是怎么写的,既可以一次read 100个字节,也可以一次read一个字节,重复100次;

那什么是粘包问题呢?

  • 首先要明确,粘包问题中的 “包” ,是指的应用层的数据包。

  • 在TCP的协议头中,没有如同UDP一样的 “报文长度” 这样的字段,但是有一个序号这样的字段。

  • 站在传输层的角度,TCP是一个一个报文过来的。按照序号排好序放在缓冲区中。

  • 站在应用层的角度,看到的只是一串连续的字节数据。

  • 那么应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始到哪个部分,是一个完整的应用层数据包。

那么如何避免粘包问题呢

归根结底就是一句话,明确两个包之间的边界

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

🌸思考:

对于UDP协议来说,是否也存在 “粘包问题” 呢?

  • 对于UDP,如果还没有上层交付数据,UDP的报文长度仍然在。同时,UDP是一个一个把数据交付给应用层。就有很明确的数据边界。
  • 站在应用层的站在应用层的角度,使用UDP的时候,要么收到完整的UDP报文,要么不收。不会出现"半个"的情况。

🌴TCP异常情况

进程终止:进程终止会释放文件描述符,仍然可以发送FIN。和正常关闭没有什么区别。

机器重启:和进程终止的情况相同。

机器掉电/网线断开:接收端认为连接还在,一旦接收端有写入操作,接收端发现连接已经不在了,就会进行reset。即使没有写入操作,TCP自己也内置了一个保活定时器,会定期询问对方是否还在。

如果对方不在,也会把连接释放。另外,应用层的某些协议,也有一些这样的检测机制。

例如HTTP长连接中,也会定期检测对方的状态。例如QQ,在QQ断线之后,也会定期尝试重新连接

⭕TCP小结

为什么TCP这么复杂?因为要保证可靠性,同时又尽可能的提高性能。

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

提⾼性能:
• 滑动窗⼝
• 快速重传
• 延迟应答
• 捎带应答
其他:
• 定时器(超时重传定时器, 保活定时器, TIME_WAIT定时器等)

基于TCP应用层协议
• HTTP
• HTTPS
• SSH
• Telnet
• FTP
• SMTP
当然, 也包括你⾃⼰写TCP程序时⾃定义的应⽤层协议;

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

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

相关文章

电脑缺少dll文件一键修复的方法,如何快速修复dll文件

如果你遇到了电脑缺少dll文件,那么也不要慌,要解决也是比较简单的,下面我们一起来了解一下电脑缺少dll文件一键修复的方法,教教大家快速修复。 一.什么是dll文件 DLL 文件全称为“Dynamic Link Library”文件,翻译为中…

美国科技行业今年裁员超 5 万人;宁德时代一年净赚超 440 亿丨 RTE 开发者日报 Vol.167

开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real Time Engagement) 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

Docker部署Django项目——基础

1.服务器配置 1.1centos7 系统的安装 centos-7-isos-x86_64安装包下载) VMware安装自定义配置 选择对应的系统镜像 一般选择内核4核、内存8g、硬盘80g 相关配置 1.2.网络配置 1.2.1查看win电脑虚拟机VMnet8的ip 使用ipconfig查看虚拟机的ip 1.2.2配置虚拟机VMnet8的ip…

膨胀 卷积

1.作用 Dilated convolution、Atrous convolution 增大感受野保持原输入大小 2.膨胀因子 描述的是相邻元素之间的距离 r 2 3.gridding effect 不合理的多个膨胀卷积之前,设计的膨胀因子不合理导致,在增大感受野的同时丢失了细节信息。 丢失&…

计算机组成原理-1-计算系统概论

1. 计算系统概论 文章目录 1. 计算系统概论1.0 课程概貌1.1 计算机系统简介1.2 计算机的硬件框图1.3 计算机的工作步骤1.4 计算机硬件的主要技术指标 本笔记参考哈工大刘宏伟老师的MOOC《计算机组成原理(上)_哈尔滨工业大学》、《计算机组成原理&#xf…

简历信息泄露?如何用图数据库技术解决简历泄露事件的反欺诈挑战

“金三银四”,又到了春招黄金期,但个人简历泄露的数据安全问题诸见报端,甚至在此前的3.15晚会报道中就揭露过招聘平台上的简历信息被泄露,不法分子通过各种渠道获取到简历,并用于欺诈活动,形成了一套庞大的…

2023年度VSCode主题推荐(个人常用主题存档)

前言 早在2018年的时候发了一篇关于VSCode主题风格推荐——VS Code 主题风格设置,时过境迁,如今常用的主题皮肤早已更替。 今天下午在整理VSCode插件的时候,不小心把常用的那款(亮色)主题插件给删除了,无…

18 优先级队列

priority_queue介绍 1.优先级队列是一种容器适配器,根据弱排序标准,它的第一个元素总是最大的 2.此上下文类似于堆,堆中可以随时插入元素,检索最大堆元素 3.优先队列实现为容器适配器,容器适配器即将特定容器类封装作…

科普文之五分钟轻松入门Generative AI

1. 引言 最近,生成式人工智能(Generative AI)在行业内带来了巨大的变动。还记得 2022 年 11 月推出的 ChatGPT 吗?在短时间内,它就成为了有史以来用户数量最快突破 1 亿的产品。 人工智能已经存在了很长一段时间&…

二叉树算法

递归序 每个节点都能回到3次! 相当于2执行完然后返回了代码会往下走,来到3节点 小总结: 也就是4节点先来到自己一次,不会执行if,先调用自己左边的那个函数,但是是null,直接返回。 这个函数执行完了,就会回到自己,调用自己右边的那个函数,结果又是空,又返回,回到…

Hive SQL必刷练习题:连续问题 间断连续(*****)

问题描述: 1) 连续问题:找出连续三天(或者连续几天的啥啥啥)。 2) 间断连续:统计各用户连续登录最长天数,间断一天也算连续,比如1、3、4、6也算登陆了6天 问题分析&am…

Kotlin进阶之协程从上车到起飞

公众号「稀有猿诉」 原文链接 Kotlin进阶之协程从上车到起飞 通过前面的一篇文章我们理解了协程的基本概念,学会协程的基本使用方法,算是正式入门了,接下来就是要深入的学习技术细节和高级使用方法,以期完全掌握Kotlin协程…

等保测评的知识

结合自己所学的知识和网络上的一些知识做个小总结。 目录 一、概念: 二、等级划分: 三、技术要求: 四、管理要求: 五、等保测评实施过程: 六、典型的网络架构: 一、概念: 全称为信息安全等级保…

HarmonyOS NEXT应用开发之Web获取相机拍照图片案例

介绍 本示例介绍如何在HTML页面中拉起原生相机进行拍照,并获取返回的图片。 效果预览图 使用说明 点击HTML页面中的选择文件按钮,拉起原生相机进行拍照。完成拍照后,将图片在HTML的img标签中显示。 实现思路 添加Web组件,设置…

mysql索引(聚簇索引,非聚簇索引:回表)( innodb 引擎库表设计注意事项)

索引文件存放位置 MyISAM 引擎每个表 都会有3个文件:表结构 (.frm) 表数据 ( .MYD) 索引 (.MYI) InnoDB 引擎每个表 都会有2个文件:表结构 (.frm)表数据索引…

flex 布局实现局部 区域滚动

需求描述: 头部固定不动,内容部分区域滚动 一、实现代码 1、实现逻辑 1. 最外层父元素,必须要flex布局,并且宽度、高度撑满可视化区域 >代码为 width: 100vw;height: 100vh; 2. 只给滚动区域设置 flex:1; overflow: scroll…

定义一个符号常量,并计算

这段代码的输出结果是什么 #include <stdio.h> #define PI 32 int main() { int iPI*2; printf("i%d\n",i);} 是7。 我问了一下AI&#xff0c;AI也回答错了&#xff0c;这是个值得注意的地方。

Error response from daemon Get server gave HTTP response to HTTPS client

使用docker compose拉起docker镜像时&#xff0c;若出现如下报错 Error response from daemon: Get "https://devops.test.cn:5000/v2/": http: server gave HTTP response to HTTPS client表示Docker守护进程无法从指定url获取响应&#xff0c; 可能原因有以下&…

苍穹外卖-day09:用户端历史订单模块(理解业务逻辑),商家端订单管理模块(理解业务逻辑),校验收货地址是否超出配送范围(相关API)

用户端历史订单模块 1. 查询历史订单&#xff08;分页查询&#xff09; 1.1 需求分析和设计 产品原型&#xff1a; 业务规则 分页查询历史订单可以根据订单状态查询展示订单数据时&#xff0c;需要展示的数据包括&#xff1a;下单时间、订单状态、订单金额、订单明细&#…

29.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-数据推测功能的算法实现

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;28.数据推测结果…
最新文章