disgare 的博客
首页
博客
分类
标签
首页
博客
分类
标签
  • 网络

    • 计算机网络学习笔记
      • 五层协议体系结构
        • 应用层
        • 传输层
        • 网络层
        • 数据链路层
        • 物理层
      • TCP 协议
        • 三次握手
        • SYN 攻击是什么,如何解决
        • 半连接队列
        • 全连接队列
        • 四次挥手
        • 发送数据全流程
        • 拥塞控制
        • KeepAlive
        • TCP 通信粘包和半包问题
        • 是什么
        • 原因
        • 处理
        • IP层会出现粘包吗
        • TCP 如何确保数据有效传输
      • UDP
      • ARQ 协议(自动重传请求)
        • 停止等待 ARQ
        • 连续 ARQ
    • 网络安全相关
    • 域名和子网掩码
    • CORS 跨域资源共享
    • DNS、HTTP 与 HTTPS
    • Server-Sent Events (SSE)
    • WebSocket 长连接
  • 计算机基础

    • 操作系统 IO 相关知识
    • 操作系统学习笔记
    • 程序的机器级表示
    • 音频文件基础
    • 正则表达式相关概念
    • ffmpeg 的安装以及实现音频切分功能
    • Hex 和 Base64 编码
    • XML 的使用
  • 数据结构与算法

    • 动态规划算法学习笔记
    • 基于比较的排序算法的最坏情况下的最优下界为什么是O(nlogn)
    • 集合与数据结构学习笔记
    • 面试常见算法总结
    • 算法导论第二部分排序学习笔记
    • 算法导论第一部分学习笔记
  • Java

    • 对象之间的映射与转换
    • 反射学习笔记
    • 泛型相关概念
    • 关于 boolean 类型的坑
    • 如何使用 lambda 表达式实现排序
    • CompletableFuture 相关用法
    • CompletableFuture 源码浅要阅读
    • FutureTask 源码阅读
    • Guava 常用 API
    • Guava 源码阅读:Multimap 相关
    • Jackson 的各种使用
    • Java 的 Excel 相关操作
    • java 的常见性能问题分析以及出现场景
    • java 基础知识
    • JAVA 枚举的基础和原理
    • Java 图片文件上传下载处理
    • Java 序列化
    • Java 异常
    • Java 语法糖
    • Java 中关于字符串处理的常用方法
    • Java 中强、软、弱、虚引用
    • JAVA 注解小结
    • Java Http 访问框架
    • Java Stream 的使用
    • Java8 新特性
    • netty 学习笔记
    • Scanner 的各种用法
    • Servlet 学习笔记
    • String、StringBuffer、StringBuilder 学习笔记
  • JVM

    • 虚拟机执行子系统
    • JVM 自动内存管理
    • Linux 中 JVM 常用工具以及常见问题解决思路
  • Linux

    • crontab 表达式
    • Linux 常见命令
    • Linux 文件系统
  • 中间件

    • 关于定时任务原理
    • 详解 kafka
    • ES 搜索引擎
    • flink 提交流程
    • Grape-RAG
    • Hadoop 基础原理
  • 多线程

    • 多线程基础学习笔记
    • 简单了解并发集合
    • 如何手写单例
    • 深入理解 java 多线程安全
    • 生产者消费者问题
    • 线程池作用、用法以及原理
    • AQS 组件
    • ThreadLocal 原理以及使用
  • 非关系型数据库

    • Redis 集群
    • Redis 数据结构、对象与数据库
    • Redis 学习笔记
  • 关系型数据库

    • B+ 树的插入、删除和数据页分裂机制
    • MySQL 的 binglog、redolog、undolog
    • MySQL 的记录存储结构、存储引擎与 Buffer Pool
    • MySQL 基本的特性
    • MySQL 开发规范
    • MySQL 事务与锁与 MVCC
    • MySQL 数据类型、字符集相关内容
    • MySQL 索引与索引优化
    • PostgreSQL 更新数据时 HOT优化
    • PostgreSQL 相关用法
  • Python

    • Python 基础语法
    • Python 学习
  • Spring 项目

    • Lombok 的常用注解
    • maven 小结
    • MyBatis 框架的使用
    • MyBatis 重要知识点总结
    • MybatisPlus 的使用
    • Spring 框架基础使用
    • Spring 事务相关
    • Spring IOC 的原理及源码
    • Spring AOP 的使用和原理
    • SpringBoot 的原理
    • SpringBoot 基础使用
    • SpringWeb 重要知识点
  • 分布式

    • 初步了解 docker
    • 从 ACID 到 BASE 事务处理的实现
    • 访问远程服务
    • 分布式 id
    • 分布式缓存相关问题
    • 分布式集群理论和分布式事务协议
    • 分布式架构的观测
    • 分布式一致性算法
    • 负载均衡 Load Balancing
    • 关于分布式系统 RPC 中高可用功能的实现
    • 集群间数据同步的目的
    • 三高问题下的系统优化
    • 数据库分库分表
    • 详解 Spring Cloud
    • Dubbo 基础概念
    • Gossip 协议
    • nginx 学习笔记
    • Protobuf 通信协议
    • Zookeeper 基础学习
  • 架构设计

    • 参数校验与异常处理
    • 抽象方法与设计模式
    • 代码整洁之道
    • 权限系统设计
    • 用低内存处理大量数据
    • 设计模式——策略模式
    • 设计模式——过滤器模式在 Spring 中的实践
    • 状态模式
    • 统一结果返回
    • 为什么要打日志?怎么打日志?打什么日志?
    • 运维监控常见指标含义
    • 资深研发进阶
    • DDD 架构学习笔记
    • Java 常用的规则引擎
    • MVC 架构学习笔记
  • AI

    • 如何编写 Prompt
    • Agent 工程架构
    • LLM 相关内容
    • NLP 相关知识
    • vibe coding 最佳实践
    • windows 下 ollama 迁移到 D 盘
  • 开发工具

    • 如何画时序图、流程图、状态流转图
    • excel 关于 =vlookup 的用法
    • git 的学习以及使用
    • IDEA 插件推荐
    • IDEA 常用快捷键以及调试
    • Shell 脚本
    • swagger 的使用
  • 前端

    • 简单了解前端页面开发
    • 伪静态是什么
    • GitHub Pages 部署教程
    • Vercel 部署教程
    • vue-admin-template 简单使用
    • VuePress 博客搭建指南
  • 项目

    • 面试刷题网——技术方案
    • 影视资源聚合站——技术方案
  • 问题记录

    • 定时任务单线程消费 redis 中数据导致消费能力不足
    • 提供可传递的易受攻击的依赖项
    • Liteflow 在 SpringBoot 启动时无法注入组件问题 couldn‘t find chain with the id[THEN(NodeComponent)]
  • 金融

    • 股票分析——关于电力
    • 股票技术面——量价关系
    • 股票技术面——盘口
    • 股票技术面——基础
    • 基础的金融知识
    • 基金与股票
    • 韭菜的自我总结
    • 聊聊价值投资
  • 其他

    • 程序员职场工作需要注意什么
    • 创业全链路SOP:从灵光一现到系统化增长的实战指南
    • 观罗翔讲刑法随笔
    • 价格和价值
    • 立直麻将牌效益理论
    • 梅花易数学习笔记
    • 压力管理
2021-02-04
计算机网络
目录

计算机网络学习笔记

# 五层协议体系结构

7层网络架构

# 应用层

应用层的任务是通过应用进程间的交互来完成特定网络应用,它定义了信息交换的格式,比如 HTTP 协议中定义了报文头报文体,协议双方按这种规则来发送接受数据

这一层传输的东西叫应用层报文

如果是七层体系结构,应用层还有表示层和会话层。OSI 的七层体系结构概念清楚,理论也很完整,但是它比较复杂而且不实用,而且有些功能在多个层中重复出现。但是如此细致的分层可以让我们对网络的理解更进一步

比如在 OSI 分层的时候,会话层在第五层,用来给不同的应用建立与管理会话。表示层在第六层,用于数据的解密、加密、翻译以及压缩等操作。第七层就是应用层,每个安装在电脑上的软件在这一层发挥作用

拿 dubbo 服务调用来举例,dubbo 的 RPC 协议在第五层,对上层封装了服务调用的过程,作用就是将数据发送到另外一台机器上。dubbo 的各种序列化协议在第六层,用于处理数据的转换,转换后的数据提供给第七层使用

常用的协议有以下几种:

  • DNS:管理域名与 IP 地址映射关系的分布式数据库
  • HTTP 协议:超文本传输信息,为了提供一种发送接受 HTML 文件的方法
  • FTP 协议:文件传输协议,20端口用于传输数据,21端口用于传输控制信息

常见端口有以下几种:

  • HTTP:80、8080(阿帕奇)
  • HTTPS:443
  • MySQL:3306
  • FTP:20,21
  • DNS:53
  • Redis:6379
  • Nacos:8848

# 传输层

传输层的主要任务就是负责向两台终端设备进程之间的通信提供通用的数据传输服务,对上层数据进行封装切割等操作,以及保证数据传输的准确性

传输层的协议 TCP 或 UDP 加上端口就可以标识一个应用层协议,TCP/IP 协议中的端口范围是从 0~65535

传输层主要传输 TCP 报文和用户数据报,这一层的主要协议如下:

  • TCP 协议:传输控制协议
  • UDP 协议:用户数据协议
  • ARQ 协议:自动重传请求

# 网络层

网络层的任务是选择合适的路由,为分组交换网上的不同主机提供通信服务

在计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点,确保数据及时传送

这一层传输的东西叫 IP 数据报,因为这一层使用的协议叫 IP 协议,因此互联网的网络层也叫做网际层或 IP 层

  • IP 网际协议 :网际协议 IP 是 TCP/IP 协议中最重要的协议之一,也是网络层最重要的协议之一,IP 协议的作用包括寻址规约、定义数据包的格式等等,是网络层信息传输的主力协议
  • ARP 协议 :ARP 协议,全称地址解析协议(Address Resolution Protocol),它解决的是网络层地址和链路层地址之间的转换问题,因为一个 IP 数据报在物理上传输的过程中,总是需要知道下一跳(物理上的下一个目的地)该去往何处,但 IP 地址属于逻辑地址,而 MAC 地址才是物理地址。具体来说是 IP 地址转 MAC 地址的一些问题
  • NAT 网络地址转换协议:NAT 协议(Network Address Translation)的应用场景如同它的名称——网络地址转换,应用于内部网到外部网的地址转换过程中。具体地说,在一个小的子网(局域网,LAN)内,各主机使用的是同一个 LAN 下的 IP 地址,但在该 LAN 以外,在广域网(WAN)中,需要一个统一的 IP 地址来标识该 LAN 在整个 Internet 上的位置

为啥要有 NAT 呢,因为 IPv4 地址已经基本用完了,而 NAT 协议可以将一个局域网内的多个主机使用同一个公网 IP 地址来访问互联网,从而节省了公网 IP 地址的浪费。我们在自己的机器上看见的 IP 地址都是局域网地址,对外暴露的地址是从运营商获得的公有 IP 地址,登录路由器管理界面可以查看

关于这个问题 IPv6 是根本的解决方案。IPv6地址长度为128位,总量是2^128个,这是一个天文数字(约340万亿亿亿亿个),可以为地球上的每一粒沙子都分配一个IP地址。IPv6正在全球范围内稳步部署

# 数据链路层

数据链路层的作用是将网络层交下来的 IP 数据报组装成帧,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)

这一层传输的东西叫帧,一般使用的是以太网协议,也可能使用IEEE802.3、IEEE802.4等协议

帧头包含同步信息,地址信息,差错检测等信息,这样可以知道帧从哪开始、进行差错处理、了解目的地址与源地址。这里的差错校验与网络层校验的不同是,这里哦只保证一段链路的数据传输的准确性,而网络层保证的则是两个节点的准确性

Wi-Fi 就是物理层和数据链路层的东西。Wi-Fi 取代的是以太网的网线和交换机上的口,通过无线电波来收发信息

# 物理层

物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异,从网络层的第一层开始,已经对上层屏蔽下层的东西了,这里做的是现实事件到网络世界的转换。如果是4层网络模型,会将数据链路层与物理层糅合在一起 4层网络架构

这一层传输的东西叫比特,就是代表0或者1的电流

# TCP 协议

三大特点:面向链接,可靠,字节流,某一特点都能说个一章节。TCP 为每个数据流初始化并且维护状态信息,比如窗口大小、端口等等,这些数据主要为了实现可靠性和流量控制

# 三次握手

1,客户端向服务器发送连接请求,即发送 SYN 报文,此时请求里包含 seq = x

开始,SYN 报文不能携带数据,需要消耗一个序列号。发送方进入 synsend(同步发送)状态

2,服务器接到请求后,向客户端返回响应,也是 SYN 报文,此时:

ACK = 1(表示是否允许链接),ack = x + 1(根据接受的请求动态算出来的,发送回去用于对客户端确定序列号),seq = y

SYN 报文不能携带数据,需要消耗一个序列号,接收端进入 synrcvd(同步接受)状态

3,客户端向服务器回复响应,此时:

ack = y + 1,ACK = 1,seq = x + 1

可以携带报文,不携带报文不消耗序列号,接收端进入连接状态

  • 为什么要回传 syn?

TCP 中只要是数据,即使是一个字节,即使如 SYN,也需要确认的,毕竟可以发送报文只代表了客户端可以正常发送,并没有证明发送端可以正常接受报文

  • 为什么最后还要发送一次确认/为什么不是两次握手/为什么服务器接受到连接请求后不直接建立连接

为了避免连接资源被浪费

1,为了确定服务器接受正常、发送正常,客户端发送正常、接受正常

2,以上的回答有点模糊,更准确的说法是如果服务器发送的 syn 报文丢失,接收端没有建立连接但是服务器建立了连接,连接资源会被浪费

3,如果发送端的第一次请求因为延迟收到了,但是此时接收端已经接受了第二次请求并且已经传输完数据然后关闭连接了,此时此前滞留的那一次请求连接,网络通畅了到达了服务器,此时连接资源会被浪费

# SYN 攻击是什么,如何解决

在短时间内伪造大量不存在的 IP 地址,并向 Server 不断地发送 SYN 包,Server 则回复确认包,并等待 Client 确认,由于源地址不存在,因此 Server 需要不断重发直至超时,这些伪造的 SYN 包将长时间占用未连接队列,导致正常的 SYN 请求因为队列满而被丢弃

怎么解决呢:

1,缩短半连接等待时间 2,短时间受到某 IP 的重复 SYN 则丢弃后续请求 3,通过半连接队列的后备设置来解决

# 半连接队列

半连接状态,指 TCP 状态为 SYN_RCVD 的状态。服务器处于 Listen 状态时收到客户端 SYN 报文时放入半连接队列中

当 SYN queue 满了,系统会根据内核参数 net.ipv4.tcp_syncookies 的值来处理请求,tcp_syncookies 是用来防止 SYN flood 攻击

原理是在半连接队列满时,服务端并不丢弃 SYN 请求,而是将源目的 IP、源目的端口号、接收到的 client 端初始序列号以及其他一些安全数值等信息进行 hash 运算,并加密后得到一个 SYN cookie

server 端发送初始序列号为 cookie 的 SYN+ACK 包,并不会保存这个 cookie。如果接收到客户端的 ACK 包,server 端将 client 端的 ACK 序列号减 1 得到的值,与上述要素 hash 运算得到的值比较(这些值也是客户端的 ack 包带过来的),如果相等,直接完成三次握手,构建新的连接

# 全连接队列

全连接状态,指 TCP 状态为的状态 ESTABLISHED。TCP 的连接状态从服务器(SYN+ACK)响应客户端后,到客户端的 ACK 报文到达服务器之前,则一直保留在半连接状态中;当服务器接收到客户端的 ACK 报文后,该条目将从半连接队列移到全连接队列尾部,即 accept queue

当 Accept queue 满了以后,即使 client 端继续向 server 端发送 ACK 的包,也会不被响应,此时 ListenOverflows+1,系统会根据 net.ipv4.tcp_abort_on_overflow 参数的值来决定如何返回。值为 0 表示直接丢弃该 ACK,但不会将连接信息从 SYN queue 队列中移除。当系统丢弃了最后阶段的 ACK,系统会根据参数 net.ipv4.tcp_synack_retries 的设置重新向 client 端发送 SYN+ACK 包。而 client 端在收到多个 SYN+ACK 包,会认为之前的 ACK 丢包了,于是 client 端又重新向 server 端发送 ACK 包。当在 accept queue 有空闲的时候最终完成连接。如果 accept queue 始终满员,则最终 client 将收到 RST 包

# 四次挥手

1,某一方主动关闭方请求断开连接,即发送 FIN(seq = x) 标志的数据包

2,被动关闭方回发响应,此时数据包里包含

ack = x + 1,ACK = 1,seq = y

3,等待一段时间后,被动关闭方发送 FIN 报文

seq = z,ack = x + 1,ACK = 1

4,主动关闭方接受报文给出回应,并等待一段时间(俩倍的报文来回时间),断开连接

ack = y + 1,ACK = 1,seq = x + 1

5,被动关闭方接受报文,立即关闭连接

  • 为什么需要等待两个最长报文段寿命 2MSL 的时间

主要是为了接受被动方的全部数据

1,主动关闭方的最后一个报文丢失时,被动关闭方会再次发送 fin 报文

2,客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文

3,如果B没有收到自己的ACK,会超时重传FiN,那么A再次接到重传的FIN,会再次发送ACK

  • 为什么需要四次挥手,不是三次

和上面问题的理由类似,被动关闭方可能有一些数据没有发完,所以 FIN 报文与 ACK 报文需要分开

  • 服务端主动关闭连接会发生什么

如果服务端主动关闭连接,那么服务端就会先发送 fin,最后要有个 2MSL 的 TIME-WAIT。如果服务端在一段时间内主动关闭的连接比较多,则服务端会有大量的 TIME-WAIT 状态的连接要等 2MSL 时间。这导致大量端口不可用

解决思路很简单,就是让服务器能够快速回收和重用那些 TIME_WAIT 的端口资源。linux 下直接对 /etc/sysctl.conf 文件进行修改即可

同时除了四次挥手外,还可以使用 RST(reset)标识强制中断连接,发送发可以发送 RST 标识的报文,通知对方立即断开连接

# 发送数据全流程

1,数据拆分:应用层产生的数据报文通常会比 TCP 报文段允许的大小大得多。TCP 会把这些数据拆分成多个更小的片段,每个片段称为一个 TCP 报文段。每个 TCP 报文段都包含一部分应用层数据以及必要的 TCP 头信息,头部中包含源端口、目的端口、序列号、确认号、数据偏移、标志位、窗口大小、校验和、紧急指针以及选项等信息

2,传输:TCP 报文段被传输层封装并传递给网络层。网络层在每个 TCP 报文段外面再添加 IP 头部,形成 IP 数据报。IP 数据报通过网络传输,经过路由器和交换机到达目的地。在传输过程中,可能会发生分片(当数据报超过 MTU 时),这些分片会在目的地重新组装。就算 TCP 分了一次片,IP 也可能会再分一次,但是出来 TCP 以外的传输层协议(UDP)可能直接依靠 IP 的分片机制

3,接收与重组:目的主机的网络层接收到 IP 数据报,将其传递给传输层。TCP 使用头部中的序列号信息将报文段重新组装成原始的数据流。即使报文段顺序到达有问题,TCP 也能根据序列号正确地重组数据

4,错误校验与确认:TCP 头部包含校验和,用于检测数据传输中的错误。接收方会对数据进行校验,确认无误后发送 ACK(确认)报文。如果报文段丢失或损坏,接收方不会发送 ACK,发送方会重传这些报文段

在整个过程中,TCP 使用流量控制(滑动窗口机制)和拥塞控制(如慢启动、拥塞避免、快速重传和快速恢复)来管理数据传输的速率,确保网络不会过载。因为滑动窗口,这期间可能发生粘包和半包问题

# 拥塞控制

1,慢启动 (Slow Start),初始状态为拥塞窗口 cwnd = 1 MSS (最大报文段大小),增长方式为每收到一个 ACK,cwnd 增加一倍,到达慢启动阈值或者丢包的时候停止增长

2,拥塞控制:当cwnd ≥ ssthresh时进入,每个 RTT 时间 cwnd 增加1 MSS(线性增长)

3,快速重传 (Fast Retransmit),发送端收到3个重复 ACK 时(表明有包丢失但后续包已到达),立即重传丢失的报文段。而超时重传则是在倒计时器到期时,还没有收到 ACK 的话,才会重试

4,快速恢复 (Fast Recovery),执行快速重传后进入,cwnd 变为当前值的一般

# KeepAlive

TCP 设有一个保活计时器,服务器每收到一次客户端的请求后,都会重新复位这个计时器,时长通常设置为2个小时,如果两个小时还没有收到客户端的任何数据,服务器就会发送探测报文段,每间隔75秒发送一次,如果一连发了10个探测报文仍然没响应,服务器就认为客户端出了问题,关闭连接

这种东西叫心跳校验机制,KeepAlive 并不是默认开启的,在 Linux 系统上没有一个全局的选项去开启 TCP 的 KeepAlive。需要开启 KeepAlive 的应用必须在 TCP 的 socket 中单独开启,默认接受时间为7200秒

有很多判断对方是否挂掉的方式都是基于 tcp 的这个校验机制,比如 http 的保活计时器、zk 集群中的心跳校验、redis 的哨兵模式等

# TCP 通信粘包和半包问题

# 是什么

TCP 粘包是指发送方多次发送的小数据包被接收方一次性接收,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾,导致 TCP 不知道这个包从哪里结束了

半包则指发送方的一个大数据包被接收方拆分成多次接收,为什么会出现这种情况呢?TCP 是面向流的协议,本身没有消息边界的概念,数据像水流一样连续传输

这个问题出现的核心原因是 TCP 是字节流服务,TCP 不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的

UDP 不可能出现粘包问题,因为它不用窗口接受,每次只接受一个数据包,每个 UDP 段都是一条消息,应用程序必须以消息为单位提取数据,而 TCP 是套接字传输方式

# 原因

TCP 粘包发生的表面原因有两点:

1,发送方如果有连续几次发送的数据都很少,通常 TCP 会根据优化算法把这些数据合成一包后一次发送出去

2,接收方如果未及时清理缓冲区的数据,造成多个包同时接收

根本原因还是因为 netty 是面向字节流的传输协议,只负责消息的传输,对消息的边界不关心

# 处理

解决粘包问题有很多方案,以下提出部分方案:

1,定长发送,发送端在发送数据时都以 LEN 为长度进行分包。这样接收方都以固定的 LEN 进行接收,如此一来发送和接收就能一一对应了。分包的时候不一定能完整的恰好分成多个完整的 LEN 的包,最后一个包一般都会小于 LEN,这时候最后一个包可以在不足的部分填充空白字节

2,头尾部标记,在每个要发送的数据包的尾部设置一个特殊的字节序列,此序列带有特殊含义,跟字符串的结束符标识”\0”一样的含义,用来标示这个数据包的末尾,接收方可对接收的数据进行分析,通过尾部序列确认数据包的边界

头部标记则是定义一个用户报头,在报头中注明每次发送的数据包大小。接收方每次接收时先以报头的 size 进行数据读取,这必然只能读到一个报头的数据,从报头中得到该数据包的数据大小,然后再按照此大小进行再次读取

3,加入消息长度信息,在收到头标志时,里面还可以带上消息长度,以此表明在这之后多少 byte 都是属于这个消息的。如果在这之后正好有符合长度的 byte,则取走,作为一个完整消息给应用层使用

你可能注意到 TCP 采用头部标记与消息长度混合使用的方式防止粘包,同时还有参数校验等辅助方法保证传输的可靠性

http 已经为我们处理了这些细节,但是如果我们直接和传输层交互,比如使用 netty 则需要额外考虑这些问题

# IP层会出现粘包吗

不会

IP 层的传输类似与 UDP 传输,每次都会接受一个被切片后的数据段,就算一个 UDP 报文被切成多个字段,经过不同的路由器传输到终点,目标机器还是一个一个接受的

# TCP 如何确保数据有效传输

1,ARQ 协议:发完一个分组就停止发送,等待对方确认,如果不能及时收到一个确认,将重发这个报文段 2,拥塞控制:当网络拥塞时,减少数据的发送 3,流量控制: TCP 连接的每一方都有固定大小的缓冲空间,流量控制是对接收方的窗口进行大小控制 4,序列号:TCP 给发送的每一个包进行编号,并根据 ack 判断这个报文序号是否正确 5,效验和: TCP 将保持它首部和数据的检验和,如果效验和有错会直接丢掉

  • 流量控制

通过滑动窗口来实现,接收端的滑动窗口可发送控制信息调整发送端窗口大小

  • 拥塞控制

控制发送端拥塞窗口的大小,使网络中数据量合理,主要由四种算法来实现

1,慢开始:由小到大逐渐增大发送窗口,每次来回大小乘二,以指数增长 2,拥塞控制:缓慢增加,每次来回大小加一 3,快重传:快速恢复丢失的数据包。如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传 4,快恢复:如果出现数据包丢失,设置慢启动阈值(ssthresh) 为当前拥塞窗口的一半

注:发送窗口通常维持在流量控制与要塞控制窗口中较小的那一个

# UDP

无连接,不可靠,基于数据报文段,一般用于实时传输数据,微信的语音聊天功能之前是使用 UDP 做的

这里重点说一下数据报文段,基于数据报是指无论应用层交给 UDP 多长的报文,UDP 都照样发送,即一次发送一个报文。至于如果数据包太长,需要分片,那也是 IP 层的事情,大不了效率低一些。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界

# ARQ 协议(自动重传请求)

用于传输层与数据链路层,它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输

# 停止等待 ARQ

传出一个数据,等待,接受回应后,继续传输 如果没有回应,重新发送 接收端收到相同数据,丢弃数据,发送回应 发送端收到相同回应,丢弃数据

# 连续 ARQ

发送端:维持一个滑动窗口,发送窗口里的所有数据 接收端:发送最后一个收到连续数据的回应

#计算机网络
最后更新: 2/25/2026, 4:06:06 AM
网络安全相关

网络安全相关→

最近更新
01
vibe coding 最佳实践
02-24
02
立直麻将牌效益理论
02-23
03
伪静态是什么
02-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式