Linux(传输层二)

news2024/10/7 12:21:57

文章目录

  • 0. 前言
  • 1. TCP协议
    • 1-1 TCP协议段格式
      • 1. TCP如何解包?
      • 2. TCP协议如何交付(应用层- - 客户)?
      • 3. 如何理解报文本身?
      • 4. 如何理解报文字段?
    • 1-2 确认应答(ACK)机制
    • 1-3 超时重传机制
    • 1-4 连接管理机制
      • 1. TCP三次握手过程
      • 2. TCP四次挥手过程
      • 3. 服务端状态转化
      • 4. 客户端状态转化
    • 1-5 理解TIME_WAIT状态
    • 1-6 理解 CLOSE_WAIT 状态
    • 1-7 代码链接

0. 前言

上一章我们主讲了UDP和端口号内容
链接:https://blog.csdn.net/Dingyuan0/article/details/129395687?spm=1001.2014.3001.5502

1. TCP协议

TCP全称为 “传输控制协议(Transmission Control Protocol”). 人如其名, 要对数据的传输进行一个详细的控制。

1-1 TCP协议段格式

在这里插入图片描述

  • 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去;
  • 32位序号/32位确认号: 后面详细讲;
  • 4位TCP报头长度: 表示该TCP头部有多少个32位bit(每一位bit代表4字节); 所以TCP头部最大长度是15 * 4 = 60
  • 6位标志位:
    • URG: 紧急指针是否有效(内容加急,不通过接收缓存区,直接交付到应用层)
    • ACK: 确认号是否有效(肯定置一有效)
    • PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走
    • RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
    • SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段
    • FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段
    • 16位窗口大小: 就是接受缓存区剩余空间的大小(传的是发送端的缓存区大小)
    • 16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也包含TCP数据部分
    • 16位紧急指针: 标识哪部分数据是紧急数据;
    • 40字节头部选项: 暂时忽略

1. TCP如何解包?

  • a.提取20字节
  • b.根据标准报头,提取4位首部长度
  • c.读取 [提取4位首部长度*4-20] 字节数据,选项
  • d.读完了报头,剩下的都是有效载荷

2. TCP协议如何交付(应用层- - 客户)?

  • 根据报头中的16位目的端口号,进行向上交付进程bind的端口

3. 如何理解报文本身?

回顾一下UDP;通过位段完成的。

4. 如何理解报文字段?

  • 我们在网络上发送的数据实际并不是直接通过网络发送的;而是通过收发缓冲区完成的。
  • 数据的发送由操作系统帮你完成; 当然通过协议来保证数据的准确性
    在这里插入图片描述

注意:
TCP没有整个报文大小,或者有效载荷???

  • TCP是面向字节流的,我们无法确定收发的次数。

1-2 确认应答(ACK)机制

样例图片:
在这里插入图片描述

  • 再举个例子,我们现在大多数人喜欢刷短视频。
    假如小麦是个宅男(而且喜欢一个女孩叫做小花),他每天给小花在微信上发消息(小花回复的很慢);小麦在这个等待小花回复的消息的过程还在不断的发,可知他无法确定小花是否收到。
    在这里插入图片描述
    (图片来源于相关教材资料)

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

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

  • 发数据1-1000,回复数据1001代表着前1000个数据都收到了。

  • 可能这时候有同学疑惑我们只要一个序列一对一回复就好了为啥还要再来个确认序号???

    • 实际上不止客户端给服务器发消息,而服务器有时候也要给客户端发一些重要数据。(用两个序号既可以发送数据又可以保证回复数据的准确性(数据收到))

在这里插入图片描述

(图片来源于相关教材资料)

1-3 超时重传机制

看名字我们就知道;时间过长,我还未收到消息,数据重新发送。
在这里插入图片描述

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

  • 如果主机A在一个特定时间间隔内没有收到B发来的确认应答, 就会进行重发
    在这里插入图片描述

    (图片来源于相关教材资料)

但是, 主机A未收到B发来的确认应答, 也可能是因为ACK丢失了
在这里插入图片描述
(图片来源于相关教材资料)

  • 因此主机B会收到很多重复数据. 那么TCP协议需要能够识别出那些包是重复的包, 并且把重复的丢弃掉,这时候我们可以利用前面提到的序列号, 就可以很容易做到去重的效果。

那么, 如果超时的时间如何确定???

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

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

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

1-4 连接管理机制

在正常情况下, TCP要经过三次握手建立连接, 四次挥手断开连接。
在这里插入图片描述
(图片来源于相关教材资料)

1. TCP三次握手过程

  • 第一次握手:客户端向服务器发送连接请求, 也就是SYN段
  • 第二次握手:服务器向客户端发送确认回复及连接请求, 也就是 SYN+ACK段
  • 第三次握手:客户端向服务器发送确认回复,也就是ACK段
    在这里插入图片描述

2. TCP四次挥手过程

第一次挥手:客户端会向服务器发送FIN段
第二次挥手:此时服务器收到FIN后, 会回应一个ACK
第三次挥手:服务器会向客户端发送一个FIN
第四次挥手:客户端收到FIN, 再返回一个ACK给服务器

在这里插入图片描述

3. 服务端状态转化

  • [CLOSED -> LISTEN] 服务器端调用listen后进入LISTEN状态, 等待客户端连接;
  • [LISTEN -> SYN_RCVD] 一旦监听到连接请求(同步报文段), 就将该连接放入内核等待队列中, 并向客户端发送SYN确认报文;
  • [SYN_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文, 就进入ESTABLISHED状态, 可以进行读写数据了;
  • [ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接(调用close), 服务器会收到结束报文段, 服务器返回确认报文段并进入CLOSE_WAIT;
  • [CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据); 当服务器真正调用close关闭连接时, 会向客户端发送FIN,此时服务器进入LAST_ACK状态, 等待最后一个ACK到来(这个ACK是客户端确认收到了FIN);
  • [LAST_ACK -> CLOSED] 服务器收到了对FIN的ACK, 彻底关闭连接。

4. 客户端状态转化

  • [CLOSED -> SYN_SENT] 客户端调用connect, 发送同步报文段;
  • [SYN_SENT -> ESTABLISHED] connect调用成功, 则进入ESTABLISHED状态, 开始读写数据;
  • [ESTABLISHED -> FIN_WAIT_1] 客户端主动调用close时, 向服务器发送结束报文段,同时进入FIN_WAIT_1;
  • [FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开始等待服务器的结束报文段;
  • [FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出LAST_ACK;
  • [TIME_WAIT -> CLOSED] 客户端要等待一个2MSL(Max Segment Life, 报文最大生存时间)的时间, 才会进入CLOSED状态。

1-5 理解TIME_WAIT状态

  • 现在做一个测试,首先启动server,然后启动client,然后用Ctrl-C使server终止,这时马上再运行server, 结果是:
    在这里插入图片描述
  • 这是因为,虽然server的应用程序终止了,但TCP协议层的连接并没有完全断开,因此不能再次监 听同样的server端口.我们用netstat命令查看一下:
    在这里插入图片描述
  • 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的时间是2MSL原因:

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

解决TIME_WAIT状态引起的bind失败的方法:

  • 使用setsockopt()设置socket描述符的选SO_REUSEADDR为1, 表示允许创建端口号相同但IP地址不同的多个socket描述符。
int opt = 1;
setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

在这里插入图片描述

1-6 理解 CLOSE_WAIT 状态

  • 我们编译运行服务器. 启动客户端链接, 查看 TCP 状态, 客户端服务器都为 ESTABLELISHED 状态, 没有问题.然后我们关闭客户端程序, 观察 TCP 状态
    在这里插入图片描述
  • 此时服务器进入了 CLOSE_WAIT 状态, 结合我们四次挥手的流程图, 可以认为四次挥手没有正确完成;
  • 小结: 对于服务器上出现大量的 CLOSE_WAIT 状态, 原因就是服务器没有正确的关闭 socket, 导致四次挥手没有正确完成 这是一个 BUG,只需要加上对应的 close(关闭文件描述符)即可解决问题。

1-7 代码链接

链接:
https://gitee.com/ding-xushengyun/linux__cpp/tree/master/23NO3_11

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

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

相关文章

Kafka中那些巧妙的设计

一、kafka的架构 Kafka是一个分布式、多分区、基于发布/订阅模式的消息队列(Message Queue),具有可扩展和高吞吐率的特点。 kafka中大致包含以下部分: Producer: 消息生产者,向 Kafka Broker 发消息的客户…

Vue3+TS项目中element-plus自动导入组件后,找不到文件

问题 原因 从报错代码来看,这是一个ts错误,而且是找不到名称 是没有将*.d.ts文件加入到tsconfig.json配置文件中,所以Typescript还不认识它们 解决 //找到项目根目录下 tsconfig.json配置文件 {"include": ["src/**/*.ts…

OpenAI-J 如何进行测试

当你检出 OpenAI-J 项目以后,你可以对 OpenAI-J 进行测试。在测试之前你首先需要获得 OpenAI 的 API Key。OpenAI 的 Key通常是以 sk 开头的字符串。最简单粗暴的办法就是把获得的 key 替换掉上面的字符串,然后进行测试就可以了。运行 Unit 测试在我们的…

Win11的两个实用技巧系列之无法联网怎么办、耳机没声音的多种解决办法

Win11无法联网怎么办? win11安装后设备不能上网的解决办法Win11无法联网怎么办?电脑安装win11系统以后,发现不能上网,连接不上网络,该怎么办呢?下面我们就来看看win11安装后设备不能上网的解决办法Win11安装后&#x…

初级篇 3 - HTML 或 CSS 文件中不懂的标签属性详解

目录一、遇到的不懂的标签属性详解1、meta 标签的 http-equiv 属性(元标签)二、遇到的 CSS 不懂的属性详解vertical-align三、如何规避 HTML 自动换行 - 脱离文档流配置属性 display: inline-block理解 inline、inline-block、blockinline总结:四、导航栏自动弹出子…

BaiduMapApi 实现ip城市获取

第一步申请百度map AK第二步 查看 百度api服务文档第三步 编写 api工具类import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; import org.springframework.stereotype.Component; import java.io.BufferedReader; import java.io.IOExceptio…

IO多路复用--[select | poll | epoll | Reactor]

因为在简历上写了netty的项目,因此还是将网络底层的那点东西搞清楚。 首先希望明确的是,BIO、NIO、IO多路复用这是不同的东西, 我会在本文中详细讲出来。 本文参考资料: JAVA IO模型 IO多路复用 select poll epoll介绍 从BIO到epo…

C/C++每日一练(20230311)

目录 1. 计算阶乘的和 ★ 2. 基本计算器 ★★★ 3. N皇后 II ★★★ 🌟 每日一练刷题专栏 C/C 每日一练 ​专栏 Python 每日一练 专栏 1. 计算阶乘的和 计算:1!-2!3!-4!5!-6!7!-8!9!-10!,并输出计算结果。 注意:不全是…

《数据分析-JiMuReport03》JiMuReport报表设计入门介绍-新建报表

报表设计 1 新建报表 1.1 创建新的数据报表 以数据报表为例,简单介绍创建报表的过程 1.2 进入报表设计页面 如下图可见,主要分为四个模块: 模块一(左) 数据集管理报表信息数据字典 模块二(右) 这部分是对数据报表的进一步优化 模块三(上…

Java面向对象:抽象类的学习

本文介绍了抽象类的基本语法概念,什么是抽象类. Java中抽象类的语法,抽象类的特性 抽象类的作用(抽象类和普通类的区别) 用抽象类实现多态… 抽象类的学习一.什么是抽象类二.抽象类语法三.抽象类的特性四.抽象类的作用五. 抽象类实现多态一.什么是抽象类 在面向对象的概念中&am…

Vue3与Vue2的区别以及Vue3的创建

Vue3带来了什么? 1.性能的提升 打包减少;初次渲染快;内存减少。 2.源码升级 使用Proxy代替defineProperty实现响应式; 重写虚拟DOM的实现和Tree-Shaking 3.使用了Typescript 4.新的特性 composition API 组合API setup配置 re…

深度学习训练营之yolov5训练自己的数据集

深度学习训练营之训练自己的数据集原文链接环境介绍准备好数据集划分数据集运行voc_train.py遇到问题完整代码创建new_data.yaml文件模型训练时遇到的报错模型训练结果可视化参考链接原文链接 🍨 本文为🔗365天深度学习训练营 中的学习记录博客&#x1f…

【专项训练】红黑树和AVL树

红黑树和AVL树 平衡二叉树: AVL Tree,and so on 如何平衡? 如何记录高度 AVL:保证任何节点的平衡因子在[-1, 0, 1] 4种旋转操作:

Linux 练习八 (IPC 信号量)

文章目录信号量介绍信号量相关函数案例一:有亲缘关系的进程使用信号量通信案例二:无亲缘关系的进程使用信号量通信使用环境:Ubuntu18.04 使用工具:VMWare workstations ,xshell作者在学习Linux的过程中对常用的命令进行…

记录--vue3+setup+ts 知识总结

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 vue3 于 2020 年 09 月 18 日正式发布,2022 年 2 月 7 日 vue3 成为新的默认版本 距离 vue3 正式发布已经过去两年有余, 成为默认版本也过去大半年了,以前还能说是对新技术、新…

SAP 凭证修改记录CDHDR / CDPOS使用及说明

目的: 一、sap的更改记录的保存 1、所有的修改记录在表CDHDR and CDPOS 2、表CDHDR 表CDHDR记录了用户于什么时间点用什么样的事务代码修改了什么样的对象 在表CDHDR字段:Change doc. Object代表了修改的对象 3、表CDPOS 是更改记录的行项目 记录…

web实现太极八卦图、旋转动画、定位、角度、坐标、html、css、JavaScript、animation

文章目录前言1、html部分2、css部分3、JavaScript部分4、微信小程序演示前言 哈哈 1、html部分 <div class"great_ultimate_eight_diagrams_box"><div class"eight_diagrams_box"><div class"eight_diagrams"><div class&…

如何使用MyBatis框架实现对数据库的增删查改?

目录&#xff1a;1.创建MyBatis项目以及如何配置2.MyBatis操作数据库的模式3.实现增删查改注意&#xff1a;在我们操作数据库之前&#xff0c;先要保证我们已经在数据库建好了一张表。创建MyBatis项目以及如何配置我们在创建项目的时候&#xff0c;引入MyBatis相关依赖配置数据…

动态内存分配之伙伴算法

伙伴算法 伙伴算法是一种在计算机内存管理中使用的算法&#xff0c;用于分配和释放内存。它是一种基于二叉树的动态内存分配算法&#xff0c;可以高效地分配和合并内存块。伙伴算法是一种按照固定大小分配内存的算法&#xff0c;例如&#xff0c;每个内存块的大小为2的n次幂&a…

MyBatis学习笔记(十二) —— MyBatis的逆向工程

12、MyBatis的逆向工程 正向工程&#xff1a;先创建Java实体类&#xff0c;由框架负责根据实体类生成数据库表。Hibernate是支持正向工程的。 逆向工程&#xff1a;先创建数据库表&#xff0c;由框架负责根据数据库表&#xff0c;反向生成如下资源&#xff1a; Java实体类Mappe…