[Linux][网络][TCP][五][延迟应答][捎带应答][面向字节流][TCP粘包问题][TCP的异常情况]详细讲解

news2025/2/23 6:40:56

目录

  • 1.延迟应答
  • 2.捎带应答
  • 3.面向字节流
  • 4.TCP粘包问题
    • 1.什么是粘包?
    • 2.如何解决粘包问题?
    • 3.UDP是否存在粘包问题?
  • 5.TCP的异常情况
    • 1.进程终止
    • 2.机器重启
    • 3.机器掉电/网线断开
  • 6.TCP小结
  • 7.TCP/UDP对比
  • 8.理解listen的第二个参数
    • 0.铺垫
    • 1.理解


1.延迟应答

  • 如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小
    • 假设接收端缓冲区为1M,一次收到了500K的数据,如果立刻应答,返回的窗口就是500K
    • 但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了
    • 在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来
    • 如果接收端稍微等一会再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M
  • 一定要记得,窗口越大,网络吞吐量就越大,传输效率就越高,我们的目标是在保证网络不拥塞的情况下尽量提高传输效率
  • 那么所有的包都可以延迟应答么?
    • 肯定也不是
    • 数量限制:每隔N个包就应答一次
    • 时间限制:超过最大延迟时间就应答一次
    • 具体的数量和超时时间,依操作系统不同也有差异,一般N取2,超时时间取200ms
      请添加图片描述

2.捎带应答

  • 在延迟应答的基础上,很多情况下,客户端服务器在应用层也是"一发一收"的,意味着客户端给服务器说了"How are you",服务器也会给客户端回一个"Fine, thank you"
  • 那么这个时候ACK就可以搭顺风车,和服务器回应的"Fine, thank you"一起回给客户端
    请添加图片描述

3.面向字节流

  • 创建一个TCP的socket,同时在内核中创建一个发送缓冲区和一个接收缓冲区
    • 调用write时,数据会先写入发送缓冲区中
    • 如果发送的字节数太长,会被拆分成多个TCP的数据包发出
    • 如果发送的字节数太短,就会先在缓冲区里等待,等到缓冲区长度差不多了,或者其他合适的时机发送出去
    • 接收数据的时候,数据也是从网卡驱动程序到达内核的接收缓冲区
    • 然后应用程序可以调用read从接收缓冲区拿数据
    • 另一方面,TCP的一个连接,既有发送缓冲区,也有接收缓冲区,那么对于这一个连接,既可以读数据,也可以写数据
      • 这个概念叫做全双工
  • 由于缓冲区的存在,TCP程序的读和写不需要一一匹配,例如:
    • 写100个字节数据时,可以调用一次write写100个字节,也可以调用100次write,每次写一个字节
    • 读100个字节数据时,也完全不需要考虑写的时候是怎么写的,既可以一次read 100个字节,也可以一次read一个字节,重复100次

4.TCP粘包问题

1.什么是粘包?

  • 首先要明确,粘包问题中的"包",是指的应用层的数据包
  • 在TCP的协议头中,没有如同UDP一样的"报文长度"这样的字段
  • 站在传输层的角度,TCP是一个一个报文过来的,按照序号排好序放在缓冲区中
  • 但站在应用层的角度,看到的只是一串连续的字节数据
  • 那么应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始到哪个部分,是一个完整的应用层数据包
  • TCP粘包问题一般是由于缓冲区当中有不同的报文信息,当把缓冲区的数据发送到网络上的时候,就会产生粘包问题;粘包问题带来的问题是会导致对方收到网络上的数据的时候无法进行合理的拆包
    • 粘包的问题是指不同报文一起发送到网络上,则当写的缓冲区当中存在不同的报文的时候,就会发生粘包问题

2.如何解决粘包问题?

  • 要解决粘包问题,本质就是要明确报文和报文地边界
  • 对于定长的包,保证每次都按固定大小读取即可
  • 对于变长的包,可以在报头的位置,约定一个包总长度的字段,从而就知道了包的结束位置
    • 比如:HTTP报头当中就包含Content-Length属性,表示正文的长度
  • 对于变长的包,还可以在包和包之间使用明确的分隔符
    • 因为应用层协议是程序员自己来定的,只要保证分隔符不和正文冲突即可

3.UDP是否存在粘包问题?

  • 对于UDP,如果还没有向上层交付数据,UDP的报文长度仍然在,同时,UDP是一个一个把数据交付给应用层的,有很明确的数据边界
  • 站在应用层的角度,使用UDP的时候,要么收到完整的UDP报文,要么不收,不会出现"半个"的情况
  • 因此UDP是不存在粘包问题的,根本原因就是UDP报头当中的16位UDP长度记录的UDP报文的长度,因此UDP在底层的时候就把报文和报文之间的边界明确了,而TCP存在粘包问题就是因为TCP是面向字节流的,TCP报文之间没有明确的边界

5.TCP的异常情况

1.进程终止

  • 当客户端正常访问服务器时,如果客户端进程突然崩溃了,此时建立好的连接会怎么样?
    • 当一个进程退出时,**该进程曾经打开的文件描述符都会自动关闭,因此当客户端进程退出时,相当于自动调用了close函数关闭了对应的文件描述符,**此时双方操作系统在底层会正常完成四次挥手,然后释放对应的连接资源
    • 也就是说,进程终止时会释放文件描述符,TCP底层仍然可以发送FIN,和进程正常退出没有区别

2.机器重启

  • 当客户端正常访问服务器时,如果将客户端主机重启,此时建立好的连接会怎么样?
    • 当选择重启主机时,操作系统会先杀掉所有进程然后再进行关机重启,因此机器重启和进程终止的情况是一样的,此时双方操作系统也会正常完成四次挥手,然后释放对应的连接资源

3.机器掉电/网线断开

  • 当客户端正常访问服务器时,如果客户端突然掉线了,此时建立好的连接会怎么样?
    • 当客户端掉线后,服务器端在短时间内无法知道客户端掉线了,因此在服务器端会维持与客户端建立的连接,但这个连接也不会一直维持,因为TCP是有保活策略的
    • 服务器会定期客户端客户端的存在状况,检查对方是否在线,如果连续多次都没有收到ACK应答,此时服务器就会关闭这条连接
    • 此外,客户端也可能会定期向服务器"报平安",如果服务器长时间没有收到客户端的消息,此时服务器也会将对应的连接关闭
    • 其中服务器定期询问客户端的存在状态的做法,叫做基于保活定时器的一种心跳机制,是由TCP实现的
      • 此外,应用层的某些协议,也有一些类似的检测机制
      • 例如:基于长连接的HTTP,也会定期检测对方的存在状态

6.TCP小结

  • 为什么TCP这么复杂?
    • 因为要保证可靠性,同时又尽可能的提高性能
  • 可靠性:
    • 校验和
    • 序列号(按序到达)
    • 确认应答
    • 超时重发
    • 连接管理
    • 流量控制
    • 拥塞控制
  • 提高性能:
    • 滑动窗口
    • 快速重传
    • 延迟应答
    • 捎带应答
  • **其它:**定时器(超时重传定时器,保活定时器,TIME_WAIT定时器等)

7.TCP/UDP对比

  • 都说TCP是可靠连接,那么是不是TCP一定就优于UDP呢?
    • TCP和UDP之间的优点和缺点,不能简单、绝对的进行比较
    • TCP用于可靠传输的情况,应用于文件传输,重要状态更新等场景
    • UDP用于对高速传输和实时性要求较高的通信领域
      • 例如:早期的QQ,视频传输等
      • 另外UDP可以用于广播
  • TCP的可靠和UDP的不可靠都是中性词,没有任何褒贬的意思
    • 可靠意味着为了可靠性,要付出更多的代价和牺牲
    • 不可靠也并不代表是坏的,正因为不可靠,所以付出的代价更小,所以效率更高
  • 归根结底,TCP和UDP都是程序员的工具,什么时机用,具体怎么用,还是要根据具体的需求场景去判定

8.理解listen的第二个参数

0.铺垫

  • accept要不要参与三次握手的过程?
    • 不需要参与三次握手,accept从底层直接获取已经建立好的链接
    • 系统先建立好连接,然后accept才能获取对应的连接
  • 如果不调用accept,能建立连接成功吗?
    • 可以
  • 如果上层来不及调用accept,并且对端还来了大量的连接,难道所有的链接都应该先建立好吗?
    • 服务器本身要维护一个连接队列,并且不能没有,不能太长
    • 和listen的第二个参数有关

1.理解

  • Linux内核协议栈为一个tcp连接管理使用两个队列
    • **半链接队列:**用来保存处于SYN_SENT和SYN_RECV状态的请求
    • 全连接队列(accpetd队列):用来保存处于established状态,但是应用层没有调用accept取走的请求
  • 而全连接队列的长度会受到listen第二个参数的影响
  • 全连接队列满了的时候,就无法继续让当前连接的状态进入established状态了
  • 这个队列的长度是listen的第二个参数+1

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

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

相关文章

标准引领 | 竹云参编《面向云计算的零信任体系》行业标准正式发布!

近日,中华人民共和国工业和信息化部公告2024年第4号文件正式发布行业标准:YD/T 4598.1-2024《面向云计算的零信任体系 第1部分:总体架构》(后简称“总体架构”),并于2024年7月1日起正式实施。 该标准汇集大…

2024.05.08作业

登陆部分代码 /登陆槽函数 void Widget::btn_clicked() {if(edit1->text()"Admin" && edit2->text()"123456"){//登陆成功对话框QMessageBox box(QMessageBox::Information,"信息对话框","登陆成功",QMessageBox::Ok,t…

SSH隧道可以做什么?

SSH隧道是SSH协议服务端提供的一种扩展功能,一般仅在linux服务器的SSH服务端中提供,其它的如交换机、防火墙等网络设备中,虽然支持SSH协议,但多数并不提供SSH隧道功能。 所以,在通过SSH协议连接远程设备时&#xff0c…

我独自升级崛起加速器推荐 我独自升级免费加速器

近期,《我独自升级》这部动画凭借爆棚的人气,在各大平台上掀起了一阵观看热潮,其影响力不容小觑。借此时机,韩国游戏巨头网石集团敏捷响应,顺势推出了同名游戏《我独自升级:ARISE》,为粉丝们搭建…

Vue3 路由入门

先安装路由 npm i vue-router //创建路由器 import { createRouter, createWebHashHistory } from vue-router//1.导入组件 import Home from /components/Home.vue import News from /components/News.vue//2.配置路由映射规则 const routes [{name: home,path: /home,compo…

【STM32】F405/407的模块总览图,记录查看

从STM32F405/407数据手册中提取,方便以后查看。主要是什么外设连接在什么总线上,时钟频率是多少。 TIM2、3、4、5、12、13、14在APB1上,最大频率84M TIM1、8、9、10、11在APB2上,最大频率168M

吴恩达机器学习笔记:第 9 周-16推荐系统(Recommender Systems) 16.5-16.6

目录 第 9 周 16、 推荐系统(Recommender Systems)16.5 向量化:低秩矩阵分解16.6 推行工作上的细节:均值归一化 第 9 周 16、 推荐系统(Recommender Systems) 16.5 向量化:低秩矩阵分解 在上几节视频中,我们谈到了协同过滤算法&…

网络层协议之 IP 协议

IP 协议格式 4 位版本:此处的取值只有两个,4(IPv4)和 6(IPv6),即指定 IP 协议的版本。 4 位首部长度:描述了 IP 报头多长,IP 报头是变长的,因为报头中的选项部…

windows驱动开发-inf文件(一)

驱动总是和inf文件相关,在WinDDK的时候,许多inf文件都需要开发工程师手动编写,不过,现在已经可以使用inx文件来生成inf文件了,它经常用于驱动的安装和卸载;不过,并不是所有的驱动都需要使用inf文…

【 npm详解:从入门到精通】

文章目录 npm详解:从入门到精通1. [npm](https://www.npmjs.com/)的安装2. npm的基础用法2.1 初始化项目2.2 安装依赖2.3 卸载依赖2.4 更新依赖 3. npm的高级用法3.1 运行脚本3.2 使用npm scope3.3 使用npm link 4. npm资源5. 使用npm进行依赖树分析和可视化6. npm进…

数据分析从入门到精通 1.numpy剑客修炼

会在某一瞬间突然明白,有些牢笼是自己给自己的 —— 24.5.5 一、数据分析秘笈介绍 1.什么是数据分析 是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律。使得数据的价值最大化 案例: 分析用户的消…

Redis 主从复制 初步认识

文章目录 定义拓扑拓扑定义单从拓扑多从拓扑树型拓扑 使用原理建立流程持续复制 定义 Redis主从复制技术的主要满足的需求是①数据恢复②负载均衡 ①数据恢复的理解:将数据同步到多个Redis服务器中,其中一个节点数据损毁,可通过复制其他节点…

Python | Leetcode Python题解之第77题组合

题目: 题解: class Solution:def combine(self, n: int, k: int) -> List[List[int]]:ans []path []def dfs(x):remain k - len(path)if not remain:ans.append(list(path))returnif n 1 - x > remain:dfs(x 1)path.append(x)dfs(x 1)path.…

【进程间通信】共享内存

文章目录 共享内存常用的接口指令利用命名管道实现同步机制总结 System V的IPC资源的生命周期都是随内核的。 共享内存 共享内存也是为了进程间进行通信的,因为进程间具有独立性,通信的本质是两个不同的进程看到同一份公共资源,所以共享内存…

MVC 过滤器

MVC 过滤器常用有4种 Action过滤器(IActionFilter) 》 行为过滤器Result过滤器 (IResultFilter)》 视图过滤器 或 结果过滤器Exception过滤器(IExceptionFilter)》 异常过滤器Authorization过滤器&#xf…

OpenCV|简单绘制一个矩形

OpenCV中的rectangle() 为绘制矩形命令,形式如下: # (img: cv2.typing.MatLike, pt1: cv2.typing.Point, pt2: cv2.typing.Point, color: cv2.typing.Scalar, thickness: int ..., lineType: int ..., shift: int ...)cv2.rectangle(img, pt1, pt2, …

运用分支结构与循环结构写一个猜拳小游戏

下面我们运用平常所学的知识来写一个小游戏,这样能够加强我们学习的趣味性,并且能够更加的巩固我们所学的知识。 游戏代码: 直接放代码:(手势可以使用数字来代替,比如0对应石头,1对应剪刀&…

APB总线协议

一、概述 高级外围设备总线(APB)是高级微控制器总线架构(AMBA)总线层次结构的一部分,并为最小的功耗和降低接口复杂性进行了优化。AMBA APB应用于连接到任何低带宽且不需要流水线总线接口的高性能的外设。 二、APB总…

【氮化镓】GaN功率器件在转换器设计中的挑战

I. 引言(INTRODUCTION) 宽带隙(WBG)器件的重要性: 引言部分首先强调了宽带隙(WBG)器件在高频、高效率电力电子技术中的关键作用。这些器件,包括碳化硅(SiC)和氮化镓(GaN),相较于传统的硅功率器件,具有显著的优势。宽带隙半导体材料的高击穿场强允许设计更薄的漂…

linux Shell编程之条件语句

条件测试操作 test命令 条件测试操作 Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0(真true)时表示成功,返回值为非0值(假false)时表示失败或异常。 t…