跳转至

自顶向下方法

工具

  • wireshark

计算机网络和因特网

接入网

  • 无法提供主流服务的只能卫星 / 拨号
  • 到户主流服务: DSL, HFC, FTTH
    • 数字用户线 (DSL): 在电话线上使用频分复用技术, 使用双绞铜线, 上下行速率不对称
    • 混合光纤同轴网络 (HFC): 利用有线电视网络, 混合光纤和同轴电缆, 共享广播媒体, 需要考虑碰撞
    • 光纤到户 (FTTH): 主要还是一个光纤连接到多个用户
      • 主动光网络 (AON): 每个用户都有独立的光纤连接到交换机, 交换机负责转发数据
      • 被动光网络 (PON): 使用分光器将一个光纤分成多个分支,每个用户连接到一个分支, 共享带宽
  • 到户后接入方式: 以太网或 Wi-Fi
  • 广域网使用移动通信技术

网络核心

  • 通信要通过通信链路和分组交换机 (路由器与链路层交换机)
  • 多数交换机使用存储转发传输, 先接收完整分组, 再转发
    • 对于每条链路, 交换机具有一个输出队列, 存储等待转发的分组
    • 可能出现排队时延与丢包
    • 根据目的 IP 地址, 交换机查找转发表, 决定输出链路
  • 因特网由十余第一层 ISP + 数十万底层 ISP 组成, 通过对等连接和客户连接互联

分组交换网的性能

  • 时延分类
    • 处理时延: 交换机处理分组头部的时间, 包括错误检查和路由查找
    • 排队时延: 分组在输出队列中等待转发的时间
    • 传输时延: 发送分组的时间, 等于分组长度除以链路速率
    • 传播时延: 分组在链路上传播的时间, 等于链路长度除以传播速度
  • 当输出队列满时, 交换机丢弃分组 -> 丢包
  • 吞吐量: 单位时间内成功传输的分组数量

网络分层

  • 自顶向下
    • 应用层 -> 报文 -> 各种应用协议栈
    • 运输层 -> 报文段 -> 传输协议栈 (TCP, UDP)
    • 网络层 -> 数据报 -> IP 协议栈
    • 链路层 -> 帧 -> 以太网 / Wi-Fi
    • 物理层 -> 比特 -> 物理介质

应用层

  • 常见体系结构: 客户端-服务器, 对等网络 (P2P)
  • 本质上是 IPC (进程间通信), 通过套接字实现
    • 套接字本质是是应用层与运输层之间的接口, 亦称为应用编程接口 (API)
    • 应用层协议对于运输层只能进行选择协议 / 参数操作
  • 进程寻址
    • 通过主机地址 (IP) 和进程标识 (端口号) 进行寻址
    • 端口号范围: 0-65535, 0-1023 为知名端口, 1024-49151 为注册端口, 49152-65535 为动态 / 私有端口
  • 选择运输协议
    • 考虑应用需求, 如可靠性, 吞吐量, 延时, 安全性
    • TCP: 可靠, 面向连接, 提供拥塞控制, 延时较大, 支持 SSL, 适用于需要可靠传输的应用 (如 HTTP, FTP, SMTP)
    • UDP: 不可靠, 无连接, 无拥塞控制, 延时较小, 适用于实时应用 (如 DNS, VoIP)

WEB 与 HTTP

  • HTTP 是无状态的, 基于 TCP
    • 服务端默认端口: 80, HTTPS 默认端口: 443
  • HTTP 演化
    • HTTP/1.0: 每个请求 - 响应对使用一个 TCP 连接, 连接建立和关闭开销大
    • HTTP/1.1: 引入持久连接, 允许多个请求 - 响应对复用同一 TCP 连接, 减少连接开销
    • HTTP/2: 引入二进制分帧, 允许多路复用, 减少延时, 支持服务器推送与头部压缩 (重复 Header 信息缓存在两端, 只发送变化部分)
    • HTTP/3: 基于 QUIC 协议, 使用 UDP 传输, 减少连接建立时延, 解决了丢包导致的 TCP 导致的队头阻塞问题
      • 并不依赖 IP + 端口, 而是使用连接 ID 进行寻址, 支持连接迁移 (如从 Wi-Fi 切换到移动网络)
      • 1-RTT 连接建立, 0-RTT 数据传输 (之前连接过的客户端可以在连接建立前发送数据)
      • 头部压缩使用 QPACK, 解决字典与流之间的依赖问题
  • 请求报文格式
    • 请求行: 方法 + URL + HTTP 版本
    • 请求头部: 键值对
      • Host: 访问域名
      • User-Agent: 客户端 (浏览器 / 爬虫)
      • Connection: 连接选项 (如 keep-alive)
      • Cookie: 发送给服务器的 cookie 数据
      • Authorization: 认证信息 (如 Basic, Bearer token)
      • Content-Type: 请求体的内容类型
      • Content-Length: 请求体的长度
      • Accept: 可接受的响应内容类型
      • Accept-Encoding: 可接受的响应内容编码 (如 gzip)
    • 请求体: 可选, 包含要发送的数据 (如 POST 请求的表单数据)
  • 响应报文格式
    • 状态行: HTTP 版本 + 状态码 + 状态消息
    • 响应头部: 键值对
      • Content-Type: 响应体的内容类型
      • Content-Length: 响应体的长度
      • Set-Cookie: 服务器发送给客户端的 cookie 数据
      • Location: 重定向 URL
      • Cache-Control: 缓存控制指令 (如 no-cache, max-age)
      • Access-Control-Allow-Origin: CORS 相关, 允许跨域访问的来源
      • Server: 服务器软件信息
    • 响应体: 包含要返回的数据 (如 HTML 页面, 图片等)
  • HTTPS
    • HTTP + SSL/TLS, 即在 HTTP 和 TCP 之间加了一层安全协议
    • SSL 与 TLS:
      • SSL (Secure Sockets Layer): 安全套接层, 网景公司开发, 现已废弃 (存在安全漏洞)
      • TLS (Transport Layer Security): 传输层安全协议, IETF 基于 SSL 升级的标准, 目前主流版本为 TLS 1.2 和 1.3
    • 三大安全目标 (CIA):
      • 机密性 (Confidentiality): 数据加密传输, 防止被窃听 (抓包看到的是乱码)
      • 完整性 (Integrity): 引入报文摘要 (MAC), 防止数据在传输中被篡改
      • 身份认证 (Authentication): 验证服务器身份, 防止中间人攻击或钓鱼网站
    • 关键机制:
      • 混合加密: 结合了非对称加密和对称加密的优点
        • 握手阶段: 使用非对称加密 (如 RSA, ECC), 公钥加密, 私钥解密, 安全地协商出会话密钥 (慢, 但安全)
        • 传输阶段: 使用对称加密 (如 AES), 使用协商好的会话密钥进行数据传输 (快, 效率高)
      • 数字证书与 CA:
        • CA (Certificate Authority): 受信任的第三方机构, 负责签发证书
        • 证书包含: 服务器的公钥, 域名信息, 签名算法, CA 的数字签名等
        • 浏览器内置了根证书列表, 用于验证服务器发来的证书是否合法
    • 握手流程 (简述):
      • Client Hello: 客户端发送支持的加密套件列表 (算法组合) 和随机数
      • Server Hello: 服务器选定加密套件, 发送服务器证书和随机数
      • 证书验证: 客户端验证证书有效性 (过期? 域名匹配? CA 可信?)
      • 密钥交换: 客户端生成预主密钥 (Pre-Master Secret), 用服务器公钥加密后发送
      • 生成会话密钥: 双方利用随机数和预主密钥生成最终的对称密钥 (Session Key)
      • Finished: 双方发送加密的握手结束通知, 之后的所有 HTTP 数据都通过 Session Key 加密传输
  • 304 Not Modified: 客户端缓存的资源未修改, 可以直接使用缓存, 减少带宽和延时
    • 基于 if-modified-since 请求头进行条件 GET 请求
  • 206 Partial Content: 服务器成功处理了部分 GET 请求, 用于支持断点续传和分块下载
    • 基于 Range 请求头指定要获取的资源范围
  • 307 / 308 Temporary / Permanent Redirect: 临时 / 永久重定向, 客户端应使用 Location 头部提供的新 URL 进行请求
    • 相较于 301 / 302, 307 / 308 不允许改变请求方法 (如 POST 请求重定向后仍应使用 POST)

电子邮件与 SMTP

  • SMTP (Simple Mail Transfer Protocol): 基于 TCP
    • 用户代理 -> 邮件服务器 (SMTP) -> 目的邮件服务器 (SMTP) -> 用户代理
    • 端口号: 25 (服务器 -> 服务器), 587 (现代加密提交, 用户 -> 服务器), 465 (老式加密提交)
    • 邮件格式: 包含邮件头部 (如 From, To, Subject) 和邮件体
    • SMTP 的过程类似具有重试机制的消息队列
    • 为了向后兼容, SMTP 传递多媒体文件时, 需要将其编码为 ASCII 字符串
  • 邮件流程的前三步接收方都可以保证长期在线, 但最后一步用户代理不一定在线, 因此需要使用 POP3 或 IMAP 协议来主动接收邮件
    • POP3: 基于 TCP, 端口号 110, 简单的邮件访问协议, 下载邮件到本地后删除服务器上的邮件
    • IMAP: 基于 TCP, 端口号 143, 功能更强大的邮件访问协议, 支持在服务器上管理邮件 (如标记已读/未读), 同步多个客户端
    • 或者使用 Webmail 通过 HTTP 协议访问邮件服务器, 如 Gmail, Outlook 等

DNS

  • 将域名解析为 IP 地址的系统, 基于 UDP (查询) 和 TCP (区域传输)
    • 端口号: 53 (DNS 查询)
    • 或者将域名别名解析为规范主机名 + IP (CNAME 记录)
    • 可解析到多个可能的 IP 地址 (负载均衡)
  • 分层 DNS 服务器
    • 根 DNS 服务器: 存储顶级域 (如 .com, .org) 的权威服务器位置
    • 顶级域 DNS 服务器: 存储各个二级域 (如 example.com) 的权威服务器位置
    • 权威 DNS 服务器: 存储特定域名的 IP 地址记录
    • 真实流程是, 客户端直接向本地 DNS 服务器要求递归查询 (直接出结果), 本地 DNS 服务器负责查询根 DNS -> 顶级域 DNS -> 权威 DNS, 最后返回结果给客户端
    • 本地 DNS 服务器可以实现缓存, 减少查询时延和根 DNS 服务器的负载
  • 格式: name value type ttl (记录生存时间)
    • 当 type 为 A 时, 主机名 -> IPv4 地址
    • 当 type 为 AAAA 时, 主机名 -> IPv6 地址
    • 当 type 为 CNAME 时, 主机名 -> 规范主机名 (别名解析)
    • 当 type 为 MX 时, 主机名 -> 邮件服务器规范主机名 (目的是邮件服务器共用域名)
    • 当 type 为 NS 时, 域名 -> 下一层 DNS 服务器的主机名 (权威服务器位置)
      • 需要一个额外的 A 记录来解析下一层 DNS 服务器的 IP 地址 (粘合记录)
  • 报文
    • 首部: 标识符 (ID), 标志位 (QR (问答), AA (是不是权威), RD (需不需要递归), RA (可不可以递归)), 后面的数量字段 (问题数, 回答数, 权威数, 附加数)
    • 问题区域: 包含查询的名字和类型
    • 回答区域: 包含查询结果的资源记录 (RR), 每条 RR 包含名字, 类型, 值, TTL
    • 权威区域: 包含其他权威服务器的记录
    • 附加区域: 包含其他辅助信息 (如粘合记录)

P2P

  • BitTorrent / DHT (分布式散列表) 等
  • 对等网络的最小下载时间是以下的最大值
    • 下载者数量 * 文件大小 / 上传速率总和
    • 文件大小 / 最快服务器的上传速率
    • 文件大小 / 最慢下载者的下载速率
  • BitTorrent
    • Tracker: 服务器, 维护种子文件和下载者列表, 协助下载者找到彼此
    • 最稀缺优先: 下载者优先下载附近的稀缺块, 以增加块的均匀分布
    • tit-for-tat: 选择附近上传速率最高的四个下载者合作

视频流和内容分发网

  • DASH (经 HTTP 的动态适应性流)
    • 通过 HTTP 协议实现自适应流媒体传输, 根据网络条件动态调整视频质量
  • CDN (内容分发网)
    • 在接入 ISP 附近部署缓存服务器, 将内容分发到离用户最近的服务器上, 减少网络延迟和带宽消耗
    • 也就是因特网交换点 (IXP) 位置
    • 依赖 DNS 实现透明

应用层增补

Telnet 与 SSH

  • 均为远程登录协议, 允许用户通过网络控制远程主机
  • Telnet (Teletype Network):
    • 端口号: 23
    • 基于 TCP
    • 采用明文传输, 包括用户名和密码, 极不安全, 容易被窃听
  • SSH (Secure Shell):
    • 端口号: 22
    • 基于 TCP
    • 提供加密通信, 保证数据机密性和完整性
    • 支持服务器身份认证, 防止中间人攻击
    • 除了远程登录, 还支持端口转发 (隧道) 和安全文件传输 (SFTP)

WebSocket

  • 一种在单个 TCP 连接上进行全双工通信的协议
  • 解决了 HTTP 协议在实时通信方面的缺陷 (HTTP 是单向的, 且头部开销大)
  • 建立过程 (握手):
    • 客户端发送 HTTP 请求, 包含 Upgrade: websocket 和 Connection: Upgrade 头部
    • 服务器响应 101 Switching Protocols, 连接升级为 WebSocket
  • 特点:
    • 建立连接后, 数据帧头部非常小, 开销低
    • 服务器可以主动向客户端推送数据 (真正的双向通信)
    • 依然使用 80 (WS) 或 443 (WSS) 端口, 容易穿透防火墙

FTP 与 SFTP

  • FTP (File Transfer Protocol):
    • 端口号: 21 (控制连接), 20 (数据连接, 主动模式)
    • 基于 TCP
    • 带外控制: 控制信息 (命令) 和数据传输使用不同的 TCP 连接
      • 控制连接: 也就是 21 端口, 贯穿整个会话期间, 保持状态 (如当前目录)
      • 数据连接: 用于传输文件或目录列表, 传输完毕后关闭 (非持久)
    • 传输模式:
      • 主动模式 (PORT): 客户端监听端口, 服务器主动发起数据连接 (容易被客户端防火墙拦截)
      • 被动模式 (PASV): 服务器开启随机端口告知客户端, 客户端主动发起连接
    • 缺点: 明文传输, 甚至密码也是明文
  • SFTP (SSH File Transfer Protocol):
    • 端口号: 22 (随 SSH)
    • 基于 SSH 协议提供的安全隧道
    • 不是 FTP 的加密版 (那是 FTPS), 而是一个全新的协议
    • 整个会话完全加密, 安全性高, 但传输效率略低于 FTP

DHCP

  • DHCP (Dynamic Host Configuration Protocol): 动态主机配置协议
    • 允许主机自动获取 IP 地址, 子网掩码, 默认网关, DNS 服务器地址等信息
    • 基于 UDP
    • 客户端端口: 68, 服务器端口: 67
  • 工作流程 (DORA):
    • DHCP Discover: 新加入的主机广播发现报文 (源 IP 0.0.0.0, 目的 IP 255.255.255.255), 寻找 DHCP 服务器
    • DHCP Offer: 收到发现报文的 DHCP 服务器广播提供报文, 预分配一个 IP 地址 (包含事务 ID, IP 地址, 租期)
    • DHCP Request: 客户端选择一个服务器 (如果有多个), 广播请求报文, 确认使用该 IP (同时也告知其他服务器可以回收它们的预分配 IP)
    • DHCP ACK: 被选中的服务器广播确认报文, 正式将 IP 分配给客户端

运输层

  • 主要协议: TCP (Transmission Control Protocol), UDP (User Datagram Protocol)
  • 运输层协议提供进程间端到端的通信服务, 可以提供网络层没有的功能 (如可靠传输, 流量控制, 拥塞控制)
    • 将主机间的连接抽象为进程间的连接, 本质上是多路复用

多路复用与多路分解

  • 不同套接字的信息打上标记 -> 多路复用
  • 解码标记交付给正确的套接字 -> 多路分解
  • 为此, 必须使用必要的信息来区分不同的套接字
    • UDP: 目的 IP + 目的端口
    • TCP: 源 IP + 源端口 + 目的 IP + 目的端口
  • TCP 为什么是四元组
    • TCP 需要四元组来区分相同目的不同来源的报文段
    • TCP Web 服务器必须包含一个监听套接字和若干个已连接套接字
    • 监听套接字监听端口 80, 只知道目的 IP 和目的端口 (服务器的地址), 无法区分不同客户端 (首次通信负责握手)
    • 已连接套接字是监听套接字接受连接时创建的, 包含了客户端的源 IP 和源端口, 可以区分不同客户端的连接 (建立连接)

UDP

  • 无连接, 不可靠, 无拥塞控制, 头部开销小 (8 字节)
  • 报文段结构
    • 源端口 (16 位)
    • 目的端口 (16 位)
    • 长度 (16 位): 包括头部和数据的总长度
    • 校验和 (16 位): 包括伪首部 (IP 头部的一部分), UDP 头部和数据, 用于错误检测
    • 数据: 可选, 包含要传输的应用数据
  • 虽然很多链路层协议 (如以太网) 都提供了错误检测机制, 但不能保证全链路都有

可靠数据传输

  • 通过可靠数据传输协议 (RDT) 实现, 运行在不可靠的网络层之上, 将下层的不可靠信道抽象为可靠信道
  • 考虑比特翻转
    • 比特翻转: 由于物理线路噪声引起的错误, 导致分组中的一个或多个比特发生改变
    • 需要引入差错检测机制 (如检验和) 来判断分组是否受损
    • 接收方需要反馈 ACK 或 NAK 来告知发送方分组是否正确接收
  • ACK / NAK 受损怎么办
    • 引入序号 (Sequence Number) 来区分新包和重传包
    • 发送方根据 ACK 的序号判断是否需要重传 (只需要一个 bit)
  • 其实不需要 NAK
    • 可以发送上一个正确接收分组的 ACK 来代替 NAK 的功能 (冗余 ACK)
  • 考虑丢包
    • 丢包: 分组在传输过程中丢失, 没新包 / 发送方没有收到 ACK, 导致卡死
    • 需要引入超时重试
  • 停等协议太慢了
    • 流水线: 允许发送方在等待 ACK 的同时继续发送下一个分组
    • 现在序号不再只是 0 和 1, 需要更大的序号空间来区分多个未确认的分组
    • GBN 和 SR 是两种经典的流水线协议, TCP 是它们的混合体
  • GBN 回退 N 步
    • 维护一个发送窗口, 允许发送 N 个未确认的分组
    • 将序号空间划分为已确认, 已发未确认, 可用但未发, 不可用四类
    • 发送方只为最早的未确认分组设置定时器, 一旦超时, 重传所有未确认分组
    • 接收方只接受按序到达的分组, 乱序分组直接丢弃, 并重复发送 ACK 来告知最后一个正确接收的分组
  • SR 选择重传
    • 窗口长度必须小于等于序号空间的一半, 否则接收方无法区分新分组和旧分组的重传
    • 发送方为每个分组设置定时器, 超时只重传该分组
    • 接收方接受乱序分组, 缓存起来, 等缺少的分组到达后再一起交付上层
    • 发送方和接收方的窗口基序号可能不同步 (因为 ACK 在路上), 需要更复杂的逻辑来管理窗口

TCP

  • 三次握手期间设置发送 / 接收缓存, TCP 异步取出数据发送, 应用层异步取出数据接收
  • MSS (Maximum Segment Size, 最大报文段长度): TCP 报文段中数据部分的最大长度, 由双方在连接建立时协商确定
    • 通常为 1460 字节 (以太网 MTU (Maximum Transmission Unit 最大传输单元) 1500 - IP 头部 20 - TCP 头部 20)
  • 任何数据包在网络里的时间不会超过 MSL (Maximum Segment Lifetime, 最大报文段生存时间)
    • 当关闭一个 TCP 连接, 主动关闭的那一方不会立刻释放资源, 而是会等待 2 倍的 MSL
    • 确保在这个连接中产生的所有旧数据包, 在网络中彻底消失, 避免旧连接同序号数据包干扰新连接
  • 超时重试时间 = 加权平均时间 + 4 * 加权偏差
    • 加权平均时间 = (1 - a) * 旧平均时间 + a * 新样本时间
    • 加权偏差 = (1 - b) * 旧偏差 + b * |新样本时间 - 加权平均时间|
    • a 和 b 是平滑因子, 通常取值为 0.125 和 0.25, 默认超时重试时间为 1 秒
    • TCP 仅采样部分分组的往返时间, 并且不包括重传分组
    • 一旦发生重传, 就认为网络拥塞, 将超时重试时间加倍 (指数退避), 以减少重传率
    • TCP 采用单计时器, 只为最早未确认的分组设置定时器
  • ACK 序号
    • ACK 序号表示期望收到的下一个字节的序号, 也就是已经正确接收的最后一个字节的序号 + 1
    • 按序获得的段会延迟发送 ACK, 以便可能的后续段一起确认 (减少 ACK 数量)
    • 收到跳跃的段会立即发送冗余 ACK
      • 重复收到 3 个相同 ACK 序号时, 发送方立即重传该分组 (快速重传), 不需要等待超时
    • 收到填空的段会立即发送 ACK
  • 流量控制
    • 接收方维护一个接收窗口, 表示当前可接受的字节数, 发送方根据 ACK 中的窗口大小调整发送速率, 避免发送过快导致接收方缓存溢出
    • rwnd: 接收方的接收窗口大小, 由接收方在 ACK 中告知发送方
    • rwnd = 接收方缓存大小 - (已接收但未被应用层取走的字节数)
    • 当 rwnd 为 0 时, 发送方停止发送数据, 并轮询发送一字节检查, 直到 rwnd 大于 0 时恢复发送

TCP 连接管理

  • 连接建立: 三次握手 (SYN, SYN-ACK, ACK)
    • 客户端发送 SYN 报文段, 无数据, SYN 标志位为 1, 选择一个初始序号, 进入 SYN_SENT 状态
    • 服务器收到, 分配缓存与资源 (SYN 泛洪 DDOS 原理), 发送 SYN-ACK 报文段, ACK 序号为客户端的初始序号 + 1, 选择自己的初始序号, SYN 标志位为 1, 进入 SYN_RECEIVED 状态
    • 客户端收到, 分配缓存与资源, 发送 ACK 报文段, SYN 标志位为 0, ACK 序号为服务器的初始序号 + 1, 进入 ESTABLISHED 状态 (此时可以发送数据)
    • 本质目的是
      • 验证双方的发送和接收能力
      • 同步双方的初始序号
      • 防止旧连接的报文段干扰新连接 (初次连接超时)
  • 连接终止: 四次挥手 (FIN, ACK, FIN, ACK)
    • 主动关闭的一方发送 FIN 报文段, FIN 标志位为 1, 进入 FIN_WAIT_1 状态
    • 对方收到, 进入 CLOSE_WAIT 状态, 发送 ACK 报文段, ACK 序号为 FIN 报文段的序号 + 1, 我方进入 FIN_WAIT_2 状态
    • 对方发送 FIN 报文段, FIN 标志位为 1, 进入 LAST_ACK 状态
    • 我方收到, 发送 ACK 报文段, ACK 序号为 FIN 报文段的序号 + 1, 进入 TIME_WAIT 状态, 等待 2 倍 MSL 后释放资源 (对方立刻释放资源)
      • 防止对方重传 FIN 报文段我方没法回复
      • 防止旧连接的报文段干扰新连接
    • 为什么四次
      • TCP 连接是全双工的, 双方都可以独立地关闭连接, 因此需要两次 FIN 来分别关闭两个方向的通信 (半关闭)

TCP 报文段结构

  • 源端口 (16 位)
  • 目的端口 (16 位)
  • 序号 (32 位): 发送的数据字节流中的第一个字节的序号
  • 确认号 (32 位): 期望收到的下一个字节的序号
  • 首部长度 (4 位): TCP 头部的长度
    • 单位为 32 位字 (4 字节), 最小值为 5 (20 字节), 最大值为 15 (60 字节)
  • 保留字段 (6 位): 保留供将来使用, 必须为 0
  • 标志位 (6 位)
    • ACK: 确认号有效
    • RST: 重置连接
    • SYN: 同步序号, 用于连接建立
    • FIN: 结束连接
    • 未使用: URG (紧急), PSH (推送), ECE (ECN Echo), CWR (Congestion Window Reduced)
  • 窗口大小 (16 位): 接收方的接收窗口大小, 表示接收方当前可接受的字节数, 用于流量控制
  • 校验和 (16 位): 包括 TCP 头部和数据, 以及一个伪首部 (源 IP, 目的 IP, 协议类型, TCP 长度), 用于错误检测
  • 紧急指针 (16 位): 仅当 URG 标志位为 1 时有效, 未使用
  • 选项 (可选): 用于扩展 TCP 功能, 如时间戳, 窗口扩大等
  • 数据

拥塞控制原理

  • 丢包的本质是路由器缓存溢出引起的拥塞, 而不是链路物理损坏
    • 重传机制虽然解决了数据可靠性问题, 但它本身不能消除拥塞, 反而可能是导致拥塞恶化的原因
  • 何为拥塞
    • 假设路由器的缓存是无限的, 当发送速率超过链路容量时, 分组会在路由器排队等待转发, 导致排队时延增加
    • 实际上, 路由器的缓存是有限的, 当缓存满了就会丢包, 丢包就要重传, 重传又增加了供给载荷 (初始数据速率 + 重传数据速率的总和)
    • 排队时延还会导致假重传 (发送方误以为分组丢失了, 但实际上只是排队时间过长)
    • 关键节点的拥塞会导致整个网络的性能崩溃 (上游路由器的工作无用, 吞吐量趋近于 0)
  • 控制拥塞
    • 根据时延和丢包率来判断网络状态, 适当调整发送速率, 避免过度拥塞 (端到端拥塞控制, 真实方案)
    • 路由器直接告诉发送方网络拥塞了 (网络辅助的拥塞控制)

TCP 拥塞控制

  • cwnd: 拥塞窗口, 发送方维护的一个变量, 表示当前允许发送的最大字节数, 受拥塞控制算法调整
    • 待确认的字节数 <= min(cwnd, rwnd) 才能发送
    • 发送速率 = cwnd / RTT
  • 调节 cwnd 的指导
    • 丢包 -> 拥塞 -> 减小 cwnd
    • 没有丢包 -> 没有拥塞 -> 增大 cwnd
    • 不停尝试更高速率, 直到丢包为止, 后退再慢慢增加
  • TCP 拥塞控制算法
    • 慢启动
      • 连接建立时, cwnd 从 1 MSS 开始
      • 每收到一个 ACK 就增加 1 MSS (cwnd 呈指数增长, 因为 cwnd 的增加会导致更多的 ACK 到来)
      • 发生丢包时, cwnd 重置, ssthresh 设置为 cwnd 的一半
    • 拥塞避免
      • 当 cwnd 达到 ssthresh 时, 进入拥塞避免阶段, 每个 RTT 增加 1 MSS (该时间段中发送的分组的成功率乘 MSS)
    • 快速恢复
      • 当发生快速重传时, 认为发生了轻微拥塞, 将 ssthresh 设置为 cwnd 的一半, cwnd 设置为 ssthresh + 3 MSS, 然后进入拥塞避免阶段
    • 根据该算法, 一条 TCP 连接的平均吞吐量为: 吞吐量 = 窗口大小 * 0.75 / RTT
    • 考虑丢包率: 吞吐量 = 1.22 * MSS / (RTT * sqrt(丢包率))

运输层增补

BBR

TODO

QUIC

TODO

DCTCP

TODO

网络层 - 数据平面