【Linux】TCP原理

tcp协议段格式

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


tcp策略

确认应答机制(ACK)

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

 

上图,既然发送的是一个序号,为什么在协议段中要设置两个序号(序号,确认序号)?

协议段中标记位有什么用?

客户端向服务端发送数据,或者服务端向客户端发送数据,有各种各样的请求,以客户端向服务端发送数据为例:建立连接请求,端口连接请求,确认报文......,不同类型的报文有不同的标记位;


超时重传机制

对方收到数据,就是我收到了ACK;但是,我没有收到ACK,对方没有收到数据(规定);

对于丢包,有两种情况:

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

 

(2)主机 A 未收到 B 发来的确认应答, 也可能是因为 ACK 丢失了;

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

那么特点的时间间隔到达是多长呢?

网络状态是会变化的,时间间隔是和网络状态相关联的--------->时间间隔是浮点的!

超时以 500ms 为一个单位进行控制, 每次判定超时重发的超时时间都是 500ms 的整数倍.

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


连接管理机制

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

建立连接

SYN置1:请求建立连接;

三次握手:

三次握手,只是一方主动发起,三次握手的过程是双方自动的完成的;

建立连接的备注就是在赌,赌最后一个ACK对方一定收到了!

如果连接不成功?最后一个ACK没有收到怎么办?

连接重置

RST置1:reset连接重置标志位;收到该标志位的主机,要对异常连接重新释放,重新建立;

断开连接

FIN置1:通知对方, 本端要关闭了;

两次握手:

客户端给服务器断开:Client要给服务器发送的数据已经发完,没有数据可发了;

但是服务器给客户端发消息,客户端还是会给服务器ACK;

既然客户端关闭了文件描述符,为什么还可以读取消息呢?

用shutdown可以关闭读端或者写端;

为什么是四次挥手?

用最小的通信成本,建立了断开连接的共识;

双方都不通信了,并且也知道对方也不和我通信了!

四次挥手的过程也是双方自动完成的;

详谈

建立连接,为什么要三次握手?为什么不是一次握手,两次握手?

握手就是发报文;

一次握手:客户端给服务器发送SYN,这样双方默认连接建立好了;

如果一个客户端给服务器发送很多SYN,就会造成SYN洪水,浪费资源;两次握手也是如此;就是造成客户端挂掉;

虽然三次握手也会产生SYN洪水问题,但是相对于一次两次好点;

回到题目,原因:

  1. 验证全双工 ----验证网络的连通性
  2. 建立双方通信共识意愿(最小次数)


CLOSE_WAIT

如果服务器端不关闭文件描述符,就会出现CLOSE_WAIT;

我们编译运行服务器. 启动客户端链接, 查看 TCP 状态, 客户端服务器都为ESTABLELISHED 状态, 没有问题,然后我们关闭客户端程序, 观察 TCP 状态;

此时服务器进入了 CLOSE_WAIT 状态, 结合我们四次挥手的流程图, 可以认为四次挥手没有正确完成;

        对于服务器上出现大量的 CLOSE_WAIT 状态, 原因就是服务器没有正确的关闭socket, 导致四次挥手没有正确完成. 这是一个 BUG. 只需要加上对应的 close 即可解决问题;

TMIE_WAIT

主动开始断开连接,自己要处于TIME_WAIT状态,等待需要一定的时长,2*MSL;

打开服务器,用telnet连接服务器,查询:

将服务器关掉,此时服务器是主动断开连接的一方,我们可以看到客户端处于CLOSE_WAIT,

再把客户端关掉,我们就可以看到服务器处于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 的值;
MSL

MSL的TCP报文的最大生存时间;

为什么是2*MSL?

就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失(否则服务器立刻重启, 可能会收到来自上一个进程的迟到的数据, 但是这种数据很可能是错误的);

bind error问题

之前的TCP/UDP  bind  error:
进程已经退了,但是连接还在,即连接对于的端口号还在这里;

怎么解决这个问题呢?

setsockopt可以解决端口号复用问题:

流量控制

看下图:

主机A给主机B发送数据,本质就是主机A的发送缓冲区将数据发送到主机B的接收缓存区,如果主机B的接受缓冲区满了,而主机A并不知道还在发送数据,这就会造成错误;怎么办呢?

只需要在发送报文是在窗口记录自己的剩余空间发送给对方即可;

16 位数字最大表示 65535, 那么 TCP 窗口最大就是 65535 字节么?

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

其实在tcp三次握手的时候,就已经协商交换过了双方的接受能力!!!

如果接受缓冲区的剩余空间大小为0,怎么办?

这时发送方就会等待;

那主机A怎么知道主机B什么时候有空间呢?(两种方法)

1、在等待期间主机A会主动进行窗口更新(tcp报文)查看主机B是否有空间;定期发送一个窗口探测数据段, 使接收端把窗口大小告诉发送端.

2、主机B有空间后,会向主机A进行窗口更新通知;

那如果主机B的窗口大小一直不更新呢?主机A有没有什么办法尽快的让主机B向上交互?

如果想让对方尽快的处理数据,都可以设置PSH标准位:PSH:PUSH

滑动窗口

目前:滑动窗口的大小=对方同步给我的窗口大小,即对方的接受能力(暂时)

问题列表:

1、滑动窗口只能向右滑动?能不能向左滑动?

只能向右滑动,不能向左

2、滑动是一直不变的吗?可以变得吗?可以变小吗?

滑动窗口可以变大,可以变小

3、可以为0吗?

可以为0

理解滑动窗口

我们知道TCP是面向字节流,每个字节的数据都进行了编号. 即为序列号;

滑动窗口本质就是下标:

在滑动窗口中如果丢包了呢?

丢包分为三种情况:

1、最左侧报文丢失

  • 确认序号规定的约束,滑动窗口左侧不动
  • 快重传&&超时重传,对最左侧报文进行补发

如果2000号报文丢失了,但是3000,4000,5000都收到了;但是发送的ack只能是1001;

  • 当某一段报文段丢失之后, 发送端会一直收到 1001 这样的 ACK, 就像是在提醒发送端 "我想要的是 1001" 一样;
  • 如果发送端主机连续三次收到了同样一个 "1001" 这样的应答, 就会将对应的数据 1001 - 2000 重新发送;
  • 这个时候接收端收到了 1001 之后, 再次返回的 ACK 就是 7001 了(因为 2001 - 7000)接收端其实之前就已经收到了, 被放到了接收端操作系统内核的接收缓冲区中;
  • 这种机制被称为 "高速重发控制"(也叫 "快重传")

2、中间报文丢失

如果3000号报文丢失了,但是2000,4000,5000都收到了;但是发送的确认序号ack只能是2001;

窗口左侧会更新到2001;就回归到最左侧报文丢失问题;

3、最右侧报文丢失

窗口左侧更新,转换成最左侧丢失问题;

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

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

相关文章

阿里巴巴通义灵码推出Lingma SWE-GPT:开源模型的性能新标杆

阿里巴巴通义灵码团队最近开源了一款名为Lingma SWE-GPT的自动化软件改进模型。这一模型在软件工程领域的应用中表现出色,首次在SWE-bench基准测试中达到了30.20%的解决率,这一成绩比Llama 3.1 405B高出22.76%,标志着开源模型在这一领域的重大…

MySQL Workbench导入数据比mysql命令行慢

1.数据量 包含2812979条数据的csv文件 2.myql命令行用LOAD DATA INFILE命令导入 耗时1分钟13秒 3.用MySQL Workbench导入 从第一天晚上22点到次日下午16点才导入了45万条数据 4.原因 MySQL Workbench导入csv数据是使用自带的python和一系列的python代码,而mys…

Redis高可用-主从复制

这里写目录标题 Redis主从复制主从复制过程环境搭建从节点配置常见问题主从模式缺点 Redis主从复制 虽然 Redis 可以实现单机的数据持久化,但无论是 RDB 也好或者 AOF 也好,都解决不了单点宕机问题,即一旦 redis 服务器本身出现系统故障、硬…

VMware虚拟机安装Win7专业版保姆级教程(附镜像包)

一、Win7镜像下载: 链接:https://pan.baidu.com/s/1tvN9hXCVngUzpIC6b2OGrA 提取码:a66H 此镜像为Win7专业版(收藏级镜像 已自用几年),官方纯净系统没有附带任何其他第三方软件。 二、配置虚拟机 1.创建新的虚拟机。 这里我们以最新的VMware…

【C++】C++11特性(上)

✨✨欢迎大家来到Celia的博客✨✨ 🎉🎉创作不易,请点赞关注,多多支持哦🎉🎉 所属专栏:C 个人主页:Celias blog~ 目录 一、列表初始化 二、std::initializer_list 三、右值引用和移…

jmeter常用配置元件介绍总结之定时器

系列文章目录 安装jmeter jmeter常用配置元件介绍总结之定时器 5.定时器5.1.固定定时器5.2.统一随机定时器5.3.Precise Throughput Timer5.4.Constant Throughput Timer5.5.Synchronizing Timer5.6.泊松随机定时器5.7.高斯随机定时器 5.定时器 5.1.固定定时器 固定定时器Cons…

【含开题报告+文档+PPT+源码】基于Spring Boot智能综合交通出行管理平台的设计与实现

开题报告 随着城市规模的不断扩大和交通拥堵问题的日益严重,综合交通出行管理平台的研究与实现显得尤为重要。现代城市居民对于出行的需求越来越多样化,对于交通信息的获取和处理能力也提出了更高的要求。传统的交通管理方式已经难以满足这些需求&#…

并发基础:(淘宝笔试题)三个线程分别打印 A,B,C,要求这三个线程一起运行,打印 n 次,输出形如“ABCABCABC....”的字符串【举一反三】

🚀 博主介绍:大家好,我是无休居士!一枚任职于一线Top3互联网大厂的Java开发工程师! 🚀 🌟 在这里,你将找到通往Java技术大门的钥匙。作为一个爱敲代码技术人,我不仅热衷于探索一些框架源码和算法技巧奥秘,还乐于分享这些宝贵的知识和经验。 💡 无论你是刚刚踏…

万字长文解读深度学习——ViT、ViLT、DiT

文章目录 🌺深度学习面试八股汇总🌺ViT1. ViT的基本概念2. ViT的结构与工作流程1. 图像分块(Image Patch Tokenization)2. 位置编码(Positional Encoding)3. Transformer 编码器(Transformer En…

嵌入式硬件杂谈(一)-推挽 开漏 高阻态 上拉电阻

引言:对于嵌入式硬件这个庞大的知识体系而言,太多离散的知识点很容易疏漏,因此对于这些容易忘记甚至不明白的知识点做成一个梳理,供大家参考以及学习,本文主要针对推挽、开漏、高阻态、上拉电阻这些知识点的学习。 目…

使用jmeter查询项目数据库信息,保存至本地txt或excel文件1108

知识点1:使用jmeter把项目数据库的数据导出,并使用jmeter导出数据库的数据 步骤1:使用jmeter把项目数据库的数据导出 (1)测试计划-添加- 线程组setUp线程组 setUp线程组:添加-配置元件-JDBC Connection …

Flink_DataStreamAPI_输出算子Sink

Flink_DataStreamAPI_输出算子Sink 1连接到外部系统2输出到文件3输出到Kafka4输出到MySQL(JDBC)5自定义Sink输出 Flink作为数据处理框架,最终还是要把计算处理的结果写入外部存储,为外部应用提供支持。 1连接到外部系统 Flink的D…

01-Ajax入门与axios使用、URL知识

欢迎来到“雪碧聊技术”CSDN博客! 在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将…

HarmonyOS Next星河版笔记--界面开发(4)

布局 1.1.线性布局 线性布局通过线性容器column和row创建 column容器:子元素垂直方向排列row容器:子元素水平方向排列 1.1.1.排布主方向上的对齐方式(主轴) 属性:.justifyContent(枚举FlexAlign&#…

webpack loader全解析,从入门到精通(10)

webpack 的核心功能是分析出各种模块的依赖关系,然后形成资源列表,最终打包生成到指定的文件中。更多复杂的功能需要借助 webpack loaders 和 plugins 来完成。 1. 什么是 Loader Loader 本质上是一个函数,它的作用是将某个源码字符串转换成…

如何用WordPress和Shopify提升SEO表现?

选择合适的建站程序对于SEO优化非常重要。目前,WordPress和Shopify是两种备受推崇的建站平台,各有优势。 WordPress最大的优点是灵活性。它支持大量SEO插件,帮助你调整元标签、生成站点地图、优化内容结构等。这些功能让你能够轻松地提升网站…

ArcGIS Pro属性表乱码与字段名3个汉字解决方案大总结

01 背景 我们之前在使用ArcGIS出现导出Excel中文乱码及shp添加字段3个字被截断的情况,我们有以下应对策略: 推荐阅读:ArcGIS导出Excel中文乱码及shp添加字段3个字被截断? 那如果我们使用ArGIS Pro出现上述问题,该如何…

24/11/13 算法笔记<强化学习> DQN算法

DQN算法的主要特点包括: 神经网络代替Q表:在传统的Q学习中,需要维护一个Q表来存储每个状态-动作对的Q值。而在DQN中,使用神经网络来近似这些Q值,这使得算法能够处理具有大量状态和动作的问题。 经验回放(E…

Blender进阶:图像纹理节点和映射节点

13 图像纹理节点 13.1 图像纹理节点 图像纹理节点,用于加载一张贴图 加载图片后,可以从图片上取得一个像素点。 输入:一个坐标矢量 输出:该坐标的像素颜色 演示:使用合并xyz节点来指定坐标。。 13.2 多种贴图 一…

MYSQL 库,表 基本操作

相关的两个编码集(简单了解即可) 1.数据库编码集 :对将要存储的数据进行编码 2.数据库校验集:对将要执行的操作(增删查改)数据是对数据编码的校验,本质也是一种读取数据库中数据库采用的一种编码格式。 总结:数据库无论对数据做…