网络原理-------TCP协议

news/2024/7/21 23:53:38/文章来源:https://blog.csdn.net/m0_74042853/article/details/139270581

文章目录

  • TCP协议
    • TCP协议段格式
    • TCP原理
      • 确认应答机制 (安全机制)
      • 超时重传机制 (安全机制)
      • 连接管理机制 (安全机制)
      • 滑动窗口 (效率机制)
      • 流量控制 (安全机制)
      • 拥塞控制 (安全机制)
      • 延迟应答 (效率机制)
      • 捎带应答 (效率机制)
    • 基于TCP的应用层协议

TCP协议

TCP, 即 Transmission Control Protocol, 传输控制协议. 是要对数据进行一个详细的控制.

TCP协议段格式

在这里插入图片描述

  • 源/目的端口号: 表示数据是从那个进程来, 到哪个进程去.
  • 32位序号: 它指示了TCP报文中第一个数据字节的序列号.
  • 32为确认号: 表示接收方期望从发送方接收到的下一个字节的序号.
  • 4位TCP报头长度: 表示TCP头部有多少个32bit (有多少个4字节); 所以TCP头部的最大长度为 15 * 4 = 60.
  • 6位标志位:
    • URG: 紧急指针是否有效
    • ACK: 确认号是否有效
    • PSH: 提示接收端应用程序立刻从缓冲区把数据读走
    • RST: 对方要求重新建立连接, 我们把携带RST标识的称为复位报文段
    • SYN: 请求建立连接, 我们把携带SYN标识的称为同步报文段
    • FIN: 通知对方, 本端要关闭了, 我们把携带FIN标识的称为结束报文段
  • 16位窗口大小: 用于数据流的流量控制, 可以表示接收方可以接受的未确认数据的字节数量; 避免网络拥塞.
  • 16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的校验和不光包含TCP首部, 也包含TCP数据部分.
  • 16位紧急指针: 标识哪部分数据是紧急数据.

TCP原理

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

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

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

在这里插入图片描述

TCP将每个字节的数据都进行了编号, 即序列号.

在这里插入图片描述

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

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

在这里插入图片描述

主机A给主机B发送数据后, 可能因为网络拥堵等原因, 数据无法到达主机B

如果主机A在一个特定时间间隔内没有收到主机B发来的确认应答, 就会进行重传

但是主机A未收到主机B的确认应答也可能是因为ACK丢失了.

在这里插入图片描述

因此TCP会收到很多重复的数据, 那么TCP协议需要识别出哪些包是重复的包, 并把重复的包丢弃掉.

这时用我们前面的确认号, 就可以很轻易的做到.

那么, 超时的时间该如何规定呢?

最理想的情况下, 找到一个最小的时间, 保证 “确认应答” 一定能在这个时间内返回.

但是这个时间的长短, 根据网络环境的不同, 是有差异的.

如果设定的时间太长, 会影响整体的重传效率.

如果设定的时间太短, 有可能会频繁发送重复的包.

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

Linux中(BSD Unix和Windows也是如此),超时以500ms为一个单位进行控制, 每次超时重发的时间都是500ms的整数倍.

如果重发一次后, 仍然得不到应答, 等待2*500ms后在进行重传

如果仍得不到应答, 就等待4*500ms进行重传, 指数型递增.

累积到一定重传次数, TCP就会认为网络或对端主机出现异常, 强制关闭连接.

连接管理机制 (安全机制)

在正常情况下, TCP要经过三次握手建立连接, 四次挥手断开连接.

在这里插入图片描述

客户端与服务器状态转化:

  • 服务器[CLOSED -> LISTEN] 服务器调用listen后进入LISTEN状态, 等待客户端连接
  • 客户端[CLOSED -> SYN_SENT] 客户端调用connect, 发送同步报文段
  • 服务器[LISTEN -> SYN_RCVD] 一旦监听到连接请求 (同步报文段), 就将该连接放入内核等待队列中, 并向客户端发送SYN确认报文
  • 客户端[SYN_SENT -> ESTABLISHED] connect调用成功, 则进入ESTABUSHED状态, 开始读写数据
  • 服务器[SYN_RCVD -> ESTABLISHED] 服务器一旦接收到客户端的确认报文, 就进入ESTABLISHED状态, 可以进行读写数据了
  • 客户端[ESTABLISHED -> FIN_WAIT_1] 客户主动调用close时, 向服务器发送结束报文段, 同时进入FIN_WAIT_1
  • 服务器[ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接 (调用close), 服务器会收到结束报文段, 服务器返回确认报文段并进入CLOSET_WAIT
  • 客户端[FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开始等待服务器的结束报文段
  • 服务器[CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接 (需要处理完之前的数据), 当服务器真正调用close关闭连接时, 会向客户端发送FIN, 此时服务器进入LAST_ACK状态, 等待最后一个ACK到来
  • 客户端[FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的FIN (结束报文段), 进入TIME_WAIT, 并发出LAST_ACK
  • 服务器[LAST_ACK -> CLOSED] 收到ACK彻底关闭连接
  • 客户端[TIME_WAIT -> COSED] 客户端要等待一个2MSL (Max Se’gment Life, 报文最大生成时间) 的时间, 才会进入CLOSE状态

为什么TIME_WAIT的时间是2MSL?

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

滑动窗口 (效率机制)

确认应答策略是, 对每个发送的数据段, 都要给一个ACK确认应答, 收到ACK后再发送下一个数据段. 这样的话就有一个很大的缺点, 就是性能较差, 尤其是数据往返时间较长的时候.

在这里插入图片描述

既然这样一发一收的方式性能低, 那么我们一次发送多条数据, 就可以大大的提高性能 (其实是将多个段的等待时间重叠在一起).

在这里插入图片描述

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

在这里插入图片描述

那么如果出现了丢包, 如何进行重传? 这里分两种情况讨论:

情况一: 数据包已经到达, ACK被丢了.

在这里插入图片描述

这种情况下, 部分ACK丢了并不要紧, 因为可以通过后续的ACK进行确认;

**情况二:**数据包直接丢了

  • 当某一段报文丢失后, 发送端会一直收到 “1001” 这样的ACK, 就是在提醒发送端;

  • 如果发送端主机连续三次收到了同一个 “1001” 这样的回答, 就会将对应的 1001-2000 的数据重新发送;

  • 这时候接收端接收到1001-2000的数据后, 返回的就是 “7001” 了, 因为 2001-7000 的数据接收端在之前就收到了, 被放到了接收端操作系统内核的接受缓冲区

这种机制被称为 “高速重发控制” (也叫 “快重传”)

流量控制 (安全机制)

接收端处理数据的速度是有限的, 如果发送方发送数据太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送数据, 就会造成丢包, 继而引起丢包重传等一系列连锁反应.

因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫流量控制 (Flow Control);

接收端将自己可以接受的缓冲区大小放入TCP首部中的 “窗口大小” 字段, 通过ACK通知发送端;

窗口大小字段越大, 说明网络的吞吐率越高;

接收端一旦发现自己的缓冲区要满了, 就会将窗口大小设置为更小的值通知发送端;

发送端接收到这个小窗口大小后就会减慢自己的发送速度;

如果接收端发送缓冲区满了, 就会将窗口大小设置为0; 这时发送端就不再发送数据, 但是需要定期发送一个窗口探测数据段, 是接收端把窗口大小告诉发送端.

在这里插入图片描述

接收端如何把窗口大小告诉发送端呢? 回忆一下我们的TCP首部中, 有一个16位窗口字段, 就是存放了窗口大小信息;

那么问题来了, 16位数字最大表示65535, 那么TCP窗口最大就是65535吗?

并非如此, TCP首部40字节选项中还包含了一个窗口扩大因子M, 实际窗口大小是窗口字段的值左移M位;

拥塞控制 (安全机制)

TCP引入慢启动机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据;

在这里插入图片描述

此处引入一个概念为拥塞窗口;

发送开始的时候, 定义拥塞窗口大小为1;

每次收到一个ACK应答, 拥塞窗口加一;

每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小作比较, 取较小的值作为实际发送的窗口;

像上面这样的拥塞窗口增长速度, 是指数级别的. "慢启动"只是指初始时慢, 但是增长速度非常快.

为了不增长的那么快, 因此不能使拥塞窗口单纯的加倍;

为此引入一个慢启动的阈值;

当拥塞窗口超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长

在这里插入图片描述

当TCP开始启动的时候, 慢启动阈值等于窗口最大值;

在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回一;

少量的丢包, 我们仅仅是触发超时重传; 大量的丢包我们就认为网络拥塞;

当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量就会立刻下降;

总结一下:

拥塞控制, 就是TCP协议想尽可能把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案.

延迟应答 (效率机制)

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

假设接受端缓冲区为1M, 一次收到了500k的数据; 如果立刻应答, 返回的窗口就是500k;

但实际上可能处理端的处理速度很快, 10ms之内就把500k的数据从缓冲区消掉了;

在这种情况下, 接受处理端还远没达到自己的极限, 即使窗口再放大一些, 也能处理过来;

如果接收端稍微等一会儿再应答, 比如等待200ms, 那么这个时候返回的窗口大小就是1M;

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

我们的方案是:

数量限制: 每个N个包就应答一次;

时间限制: 超过最大延时时间就应答一次;

具体数量和超过时间, 依操作系统不同也有差异; 一般N取2, 最大延时时间取200ms;

在这里插入图片描述

捎带应答 (效率机制)

在延迟应答的基础上, 我们发现很多情况下, 客户端和服务器在应用层也是 “一发一收” 的. 那么当服务器给客户端回消息的时候, ACK就可以 “搭顺风车” 和服务器回应的一起返回给客户端.

在这里插入图片描述

基于TCP的应用层协议

  • HTTP
  • HTTPS
  • SSH
  • Telent
  • FTP
  • SMTP

当然, 也包括自己写TCP程序时自定义的应用层协议;

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

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

相关文章

c语言 分而治之(施特拉森矩阵乘法)

给定两个大小分别为 nxn 的方阵 A 和 B&#xff0c;求它们的乘法矩阵。 朴素方法&#xff1a;以下是两个矩阵相乘的简单方法。 void multiply(int A[][N], int B[][N], int C[][N]) { for (int i 0; i < N; i) { for (int j 0; j < N; j) { …

Vanna使用ollama分析本地MySQL数据库

上一章节中已经实现了vanna的本地运行&#xff0c;但是大模型和数据库都还是远程的&#xff0c;因为也就没办法去训练&#xff0c;这节一起来实现vanna分析本地mysql数据库&#xff0c;因为要使用本地大模型&#xff0c;所以开始之前需要给本地安装好大模型&#xff0c;我这里用…

Redis面试题深度解析

1、我看你做的项目中&#xff0c;都用到了redis&#xff0c;你在最近的项目中哪些场景使用了redis呢? 2、缓存穿透 布隆过滤器的误判现象 Redisson和Guava都对布隆过滤器进行了实现 3、缓存击穿 互斥锁&#xff0c;就是一个线程来修改&#xff0c;并占据了锁&#xff0c;另外其…

基于 Coze 从 0-1 搭建专属 小白的Bot 机器人

基于 Coze 从 0-1 搭建专属 小白的Bot 机器人 ​ 作为一个GIS从业人员&#xff0c;对于AI的使用是必不可少的&#xff0c;在过去的一两年里各种大模型频出&#xff0c;AI技术已经成为GIS领域的一项重要工具&#xff0c;为我们提供了许多强大的功能和解决方案。看到好文章都在介…

AI视频教程下载:全面掌握ChatGPT和LangChain开发AI应用(附源代码)

这是一门深入的课程&#xff0c;涉及ChatGPT、LangChain和Python。打造专注于现实世界AI集成的AI应用&#xff0c;课件附有每一节涉及到的源代码。 **你将学到什么&#xff1a;** - 将ChatGPT集成到LangChain的生产风格应用中 - 使用LangChain组件构建复杂的文本生成管道 - …

Jeecg | 完成配置后,如何启动整个项目?

前端启动步骤&#xff1a; 1. 以管理员身份打开控制台&#xff0c;切换到前端项目目录。 2. 输入 pnpm install 3. 输入 pnpm dev 4. 等待前端成功运行。 可以看到此时前端已经成功启动。 后端启动步骤&#xff1a; 1. 启动 mysql 服务器。 管理员身份打开控制台&#…

Nginx网页服务

nginx的配置: 1、全局块&#xff1a;全局配置&#xff0c;对全局生效&#xff1b; 2、events块&#xff1a;配置影响 Nginx 服务器与用户的网络连接&#xff1b; 3、http块&#xff1a;配置代理&#xff0c;缓存&#xff0c;日志定义等绝大多数功能和第三方模块的配置&#xf…

JavaDS-学习数据结构之如果从零开始手搓顺序表,顺带学习自定义异常怎么用!

前言 笔者开始学习数据结构了,虽然笔者已经会用了,不管是C 中的stl亦或是Java 中的集合,为了算法比赛多少都突击过,但只知其然而不知其所以然,还是会限制发展的,因此,笔者写下这篇博客.内容是手搓一个顺序表.顺带加一点异常的使用,大伙看个乐子就好了.有错误直接私信喷我就好了…

HarmonyOS-9(stage模式)

配置文件 {"module": {"requestPermissions": [ //权限{"name": "ohos.permission.EXECUTE_INSIGHT_INTENT"}],"name": "entry", //模块的名称"type": "entry", //模块类型 :ability类型和…

Sourcetree安装教程及使用

1 Sourcetree介绍 Sourcetree是一款免费的Git图形化客户端&#xff0c;它由Atlassian开发&#xff0c;提供了跨平台的支持&#xff0c;可运行在Windows和Mac操作系统上。Sourcetree可以让开发者更方便地使用Git来管理代码&#xff0c;不需要在命令行中输入复杂的Git命令&#x…

什么是数字化采购?一文解析!

在快速发展的数字经济时代&#xff0c;越来越多的企业开始想要了解什么是数字化采购&#xff1f;因为数字化采购已经成为提升效率、降低成本的关键举措。简单来说&#xff0c;采购数字化就是利用先进的数字化技术和工具&#xff0c;对传统的采购流程进行改造和优化&#xff0c;…

el-image本地图片不显示,提示加载失败

问题描述&#xff1a;el-image使用本地图片不显示&#xff0c;提示加载失败。 <el-image src"../../assets/img/value.png"></el-image> 解决方法&#xff1a;src用里面加个require&#xff0c;注意给 src 属性加: <el-image :src"require(../..…

sysbench压测mysql性能测试命令和报告

sysbench压测mysql性能测试命令和报告 一、安装sysbench工具二、创建测试数据库三、基于sysbench构造测试表和测试数据四、数据库性能测试1、数据库读写性能测试2、数据库读性能测试3、数据库删除性能测试4、数据库更新索引字段性能测5、数据库更新非索引字段性能测试6、数据库…

使用PySpark构建和评估逻辑回归模型预测质量是否合格

使用PySpark构建和评估逻辑回归模型预测质量是否合格 随着数据量的不断增长&#xff0c;传统的数据处理工具已经难以满足需求。PySpark作为大数据处理框架Apache Spark的Python API&#xff0c;为大规模数据处理和机器学习提供了强有力的支持。本文将详细介绍如何使用PySpark进…

必看项目|多维度揭示心力衰竭患者生存关键因素(生存分析、统计检验、随机森林)

1.项目背景 心力衰竭是一种严重的公共卫生问题,影响着全球数百万人的生活质量和寿命,心力衰竭的病因复杂多样,既有个体生理因素的影响,也受到环境和社会因素的制约,个体的生活方式、饮食结构和医疗状况在很大程度上决定了其心力衰竭的风险。在现代社会,随着生活水平的提…

Token验证流程、代码示例、优缺点和安全策略,一文告诉你。

Token和Session都是用于身份验证和授权的机制&#xff0c;而且Token渐渐成为主流&#xff0c;有不少小伙伴对token的认识不全&#xff0c;这里给大家分享下。 一、什么是Token Token是一种用于身份验证和授权的令牌&#xff0c;通常用于在客户端和服务器之间进行安全的通信。…

[C][符号]详细讲解

目录 1.算术操作符2.接续符和转义符 \1.续行符使用2.转义 3.单引号和双引号4.逻辑运算符5.位运算符6.移位操作符7. --操作8.条件操作符9.逗号表达式10.操作符的属性 1.算术操作符 算术操作符&#xff1a; - * / %除了%操作符以外&#xff0c;其他的几个操作符可以作用于整数和…

从这些原理中,读懂迅软DSE加密系统

加密技术是保护信息安全的系统&#xff0c;通过对原始数据进行加密&#xff0c;使得未经授权的人无法读取这些信息。 一、迅软DSE加密系统干什么用的&#xff1f; ★保护隐私&#xff1a;加密确保个人、机构的敏感信息在传输和存储过程中不被未授权的人访问。 ★防止数据泄露…

json/excel文件上传下载工具方法汇总

文章目录 浏览器下载json文件浏览器下载excel文件【Workbook】浏览器导入json文件【ObjectMapper】浏览器导入excel文件【Workbook】ResourceLoader读取类路径下单个jsonResourceLoader读取类路径下所有json文件 浏览器下载json文件 Operation(summary "设备模型导出(带分…

计算机图形学入门03:二维基本变换

变换(Transformation)可分为模型(Model)变换和视图(Viewing)变换。在3D虚拟场景中相机的移动和旋转&#xff0c;角色人物动画都需要变换&#xff0c;用来描述物体运动。将三维世界投影变换到2D屏幕上成像出来&#xff0c;也需要变换。 1.缩放变换 缩放(Scale)变换&#xff1a; …