#import "../template.typ": *
#show: note.with(
  title: "计算机网络",
  author: "YHTQ",
  date: none,
  logo: none,
)
#let chapter1 = [
= 前言
- 课程考核 :mooc （15%，通过即满）+4次lab取3次最高分（各10%）+期末考试（55%）
- Lab：https://n2sys-edu.github.io/Lab-Frontend-Pub/ 
- 不点名
#set heading(outlined: false)
== 通信网络：结点（Node）+链路（Link）
  - 在计算机诞生前便有许多通讯网络
  - 计算机网络：
    - 结点：个人计算机、服务器、手机、路由器、交换机.....
    - 链路：网络、光纤、无限媒介
    - 传输对象：01比特承载的数字信息
- 计算机网络技术的发展非常快，需要底层通讯技术、计算系统、应用支撑的技术支持
== 发展历史

  + 早期阶段：1983年前，早期互联网技术，美苏争霸中的科技竞争促使计算机网络技术研究的开始。最早只有几个参与研究的大学连接在这个网络中。首次创新性的采用分组交换技术（分布式架构，各个节点之间完全对等，保证了互联网结构安全性），有别于电话网络。（苏联早期多次考虑过建立国家统一网络管理国家经济，有许多超前性设计，但最终无法完成）
  + 80年代中期：Internet将多个小型网络连接成全球性网络。1983年，TCP/IP协议成为Internet的标准协议，标志现代互联网诞生。
  + 90年代互联网经历了快速发展,包括万维网、Mosaic浏览器（网景）等等重大技术出现，90年代称为Web1.0
  + 2000年互联网泡沫破灭，逐渐开始低调发展，2000-2007年称为Web2.0。2007年3G+iPhone标志着移动互联的开始
  + 2007至今 移动互联网时代，网络发展为云计算、大数据提供机遇
  从发展历程来看，早期互联网以下载为主，如今用户本身开始产生大量数据，对上行带宽提出了更高的需求
== 今天的互联网：Internet

  Internet 实际上是由大量子网络分级组成的。
  一般而言，Internet 是专有名词，是现如今连接全球的互联网。internet 泛指一类将小网络连接称大网络的网络类型

== 互联网存在的问题
  + 网络安全与威胁
  + 网络带宽的增长跟不上需求增长（传输大量数据时因特网带宽甚至不如卡车）
  + 网络管理混乱：设备数量庞大，功能复杂，许多问题难以复现与测试
未来网络需要大量新兴技术，包括网络可编程，分布式计算系统，自动化验证技术，卫星通信等等。

我国的互联网技术：底层通信强，上层互联网应用强，中间网络体系结构薄弱。

== 标准化组织与学术会议
ISO(国际标准化组织), ITU(国际电信联盟), IEEE(国际电气和电子工程师协会), WIFI联盟, 万维网联盟

ISOC(互联网协会), IAB(互联网体系结构委员会)

学术会议：

ACM SIGCOMM, USENIX NSDI, IEEE INFOCOM, ACM MOBICOM(移动互联网)

#set heading(outlined: true)
= 计算机网络的内容和分层架构
- 基本内容：信息传输
- 终极目标：更快、更稳定、更好用
- 构成：个域网、局域网、城域网、广域网
- 今天的网络：网络的网络
- ISP: Internet Service Provider / 网络服务商
- _ 注：网络传输中习惯使用 $10^3$ 为进制，以比特（bit / b）为最小单位 _ 
== 对等实体：识别，命名，组织形式
- 网络边缘：端系统
  - 主机（Host）：桌面计算机，服务器，智能设备......
  - 功能：运行应用程序，从网络接收数据并提供给应用程序，将用户产生的数据发给接入网
  - 内部架构
    - 网络设备硬件：网络适配器（网卡）
    - 操作系统内核：网卡内核驱动，内核协议栈（与网卡无关）
    - 用户软件：调用操作系统的接口（socket）进行数据发送、接收
  - 命名（确切来说是网卡的命名，以下都是以单个网卡为单位的）\
    + 唯一的设备ID（48位MAC地址），全球唯一，不可修改。（虚拟机中的虚拟网卡可以修改mac地址）
    + IP地址：一组数字，可以根据需要随时配置的地址，方便管理
    + 主机名：字符串，便于记忆

- 接入网：通信线路
  - 目的：将主机连接到边缘路由器
  - 边缘路由器：主机去往任何其他远程端设备经过的第一台路由器
  - 通过路由器统一各种异构网络
  - 各种物理介质
    - 引导型介质（有线介质）：信号在固体介质中传输
      - 双绞线（通常所谓的网线）：多根互相绝缘铜线，电话线用一对双绞线，网线用8对；广泛用于计算机网络（以太网）双向传输
      - 同轴电缆（逐渐被淘汰）
      - 光纤：玻璃纤维携带光脉冲，高速，误码率低
    - 非引导性介质（无线介质）：无具体导体
      - 无线电：电磁频谱中各波段携带信号，不依赖介质的广播
        - 半双工：两个方向都能传输，但不能同时
        - 容易受到各种形式的干扰：反射、物体阻挡、干扰、噪声
        - 链路类型：
          + WiFi（无线局域网），10米量级
          + 广域（3/4/5G），10公里范围
          + 蓝牙：短距离，有限速率
          + 地面微波：点对点，45Mbps
          + 卫星
            - 同步卫星：往返时延大
            - 低轨卫星：往返时延小，但需要大量卫星以及卫星间通讯
  - 接入方式
    + 数字用户线DSL：使用电话线连接到数字用户线接入复用器（DSLAM）\
      网络数据经过调制解调器和分路器和电话线合并，现代DSL可以同时传输语音和网络数据
    + 同轴电缆：使用传统有线电视接入头端上网，类似于DSL
    + 光纤：带宽大、线路稳定。
      - 我国由于发展较晚，互联网基建建设时大量使用光纤，因此我国的互联网基础设施较好
      - 分为有源AON和无源PON两类，也就是每个用户独立线路和用户共享线路
    + 无线接入：通过基站（“接入点”）再通过有线方式接入路由器
    - 实际家庭网络往往采用有线、无线技术混合
    - 企业可以通过交换机和专线直接连接到ISP

- 网络核心：交换设备
  - 目标：连接各个端系统
  - 由各类路由器、交换机组成
  - 数据传输方式：分组交换（包交换）
    - 主机将数据分成分组（Package），发送到网络
    - 每个分组独立的从一个路由器转发到下一个路由器，逐跳传输到目的地
    - 采用 *存储转发机制：一个分组必须被路由器完整收到再发送出去，本质上会带来额外延迟但更加稳定* 
    - 每个分组的头部都带有控制信息
     支持灵活的统计多路复用：通过灵活按需分配带宽支撑多个主机
  - 核心功能：
    - 路由：一种全局操作，通过源和目标计算数据分组传输的最优路径
    - 转发：本地操作，路由器或交换机将接收到的数据分组转发出去 
  - 瞬时拥塞：\
       当两个数据包同时到达时，由于存储转发机制可能造成一个数据包被阻塞，从而造成瞬时拥塞。如果两方数据流量很大，一方可能被阻塞很长时间，造成严重的拥塞。
  - 另一种选择：电路交换
    先呼叫建立连接确定资源预留，再传输数据（此时独占资源），传输完成后释放资源。打电话时大部分时候采用电路交换。\
    由于因特网中的数据流量很难预测（存在大量突发流量），电路交换不适用于因特网。
  - 事实上两种交换方式都存在很多问题，因此现代网络仍然在探索更先进的交换方式
- 端系统通过网络供应商接入Internet，不同网络供应商之间也要相互连接。
  - 网络供应商之间并不是全连接关系。事实上采用的途径是网络供应商连接到几个全局供应商，全局供应商之间再相互连接（连接节点称为 Internet exchange point）
  - 在一些国家，成为 ISP 的门槛很低，因此还出现了一些区域性  ISP 介于全局供应商和网络供应商之间
  - 由此供应商之间的连接关系形成了一个层次化的结构。Tier 1 的供应商互不结算，包括中国电信，中国联通等。Tier 2 的供应商与 Tier 1 的供应商结算，包括中国移动，教育网等。Tier 3 的供应商与 Tier 2 的供应商结算，包括一些区域性 ISP。
- 还有一种网络服务：CDN，通过将内容分发到离用户更近的地方，提高用户访问速度。CDN 服务商与 ISP 之间也需要相互连接。
== 服务：传输接口，服务性能，可靠性
- 服务类型
  - 面向连接服务：在数据传输前需要建立连接，如电话
    - 每个请求都需要等待答复
    - 流程:
    + 发送请求
    + 接受答复
    + 发送数据
    + 应答
    + 请求断开连接
    + 断开连接
  - 无连接服务：数据传输前不需要建立连接，如邮件
- 性能指标：
    - 吞吐量类：
        + 带宽：网络某通道传输数据的能力，单位为 bit/s，缩写为bps 
        + 包转发率：以包为单位的某网络设备的交换能力
            线速转发：在设备最大负载下，设备能够转发数据包的最大速率（显然包越大处理单个包的额外负载越小）
        + 比特率：单位时间内主机向信道发送的比特数，单位为 bps
        + 吞吐量：单位时间内通过某节点的数据量\
            由于各种原因，主机不一定可以占满介质的传输能力，因此吞吐量一般小于比特率
        + 有效吞吐量：单位时间内接收方正确接收的信息量
        + 利用率：吞吐量 / 带宽
        + 丢包率：单位时间内丢失的数据包占总发送数据包的比例
    - 延迟类：
        - 时延/延迟：数据从网络的一段传输到另一端所花的时间，分为以下四种的和
        - 传输/发送延迟：数据从结点进入到传输媒体所需要的时间
        - 传播延迟：电磁波在信道中需要传播一定距离而花费的时间
        - 处理延迟：主机或路由器在收到分组时，为处理分组（例如分析首部、提取数据、差错检验或查找路由）所花费的时间
        - 排队延迟：分包在路由器的输出队列中等待传输所花费的时间
      延迟模型：\
      传输时延 $->$ 传播时延 $->$ 排队时延 $->$ 处理时延 $->$ 传输时延 $->$ ......
      - 量级： 
        - 传输时延 + 物理时延：专用硬件可达微秒到纳秒级
        - 传播时延：与距离有关，光纤中等效约为 $2\/3$ 光速，微波中等效约为光速
        - 排队时延难以估计，严重时可达秒级。可以通过排队论进行分析：$"平均队列长度" = "平均到达速率" * "平均排队时延"$
      - 有的场景下（例如高频量化交易）对延迟极度敏感，因此需要对延迟进行极端优化。例如建立专线消除排队时延，设计专有硬件芯片和操作系统模块消除处理和传输时延，使用微波（不需要反射）在晴天时达到更小的传输时延，甚至建设中继站点等等。
      - 有时我们也会关心双向延迟，也就是一来一回总计的延迟，称为往返延迟 （Round-Trip Time，RTT）。ping指令得到的延迟便是往返延迟。
      - 时延抖动：时延的变化程度称为时延抖动，在语音视频等服务中往往会严重降低用户体验
      - 延迟丢包：在网络游戏等服务中，由于时延过大导致到达时已经无用的数据包称为延迟丢包
    - 时延带宽积：传播时延 $times$ 带宽，表示在传输过程中介质的容积。只有链路完全充满链路才能达到时延带宽积所表示的传输能力。
    - 其他指标：
      - 可靠性：发送的每个消息，接收方收到一次且仅收到一次
      - 完整性：发送的数据无法被篡改
      - 隐私性：发送的数据不被第三方截获，有时也包含发送方身份不被暴露
      - 可审计性（accountability）：可追溯用户的传输行为。由于开销过于巨大往往难以实现
== 协议：传输内容的格式、语义、顺序
- 协议：在两个或多个通信实体之间交换信息的规则
  \ 三要素：
  - 语法：规定传输数据的格式
  - 语义：规定传输数据的含义
  - 时序：规定各种操作的顺序
- 协议封装：将数据分为头部和载荷，其中头部包含协议的控制信息，载荷包含用户所发送的数据
- 常用的互联网协议（数据巨大）
  - IP / TCP / UDP / HTTP / FTP / SSH / IMTP / POP
  - WAP: Wireless Application Protocol
  - SIP: Session Initiation Protocol
  - PPP: Point-to-Point Protocol
  - IPX: Internetwork Packet Exchange
  - HIP: Host Identity Protocol (HIP)
  - IGMP: Internet Group Management Protocol, multicast
  - ICMP: Internet Control Message Protocol, e.g., ping, traceroute
  - RTP: Real-time Transport Protocol
  - PIM: Protocol-Independent Multicast
  - RED: Random early detection
  - RTCP: RTP Control Protocol (RTCP)
  - RIP: Routing Information Protocol
  - SMTP: Simple Mail Transfer Protocol
  - RTSP: Real Time Streaming Protocol
  - BFD: Bidirectional Forwarding Detection
  - CIDR: Classless Inter-Domain Routing
  - NNTP: Network News Transfer Protocol
  - STUN: Session Traversal Utilities for NAT
  - VTP: VLAN Trunk Protocol
  - POP: Post Office Protocol
  - LISP: Locator/ID Separation Protocol
  - TFTP: Trivial File Transfer Protocol
  - LDP: Label Distribution Protocol

== 实现与管理：“功能.协议$->$实体”，资源分配与调度
- 计算机网络的学习内容：网络尸体如何通过各种协议实现各种网络功能和服务

== 计算机网络的分层架构
- 计算机网络是一个高度复杂的系统，通过分层架构解决系统的复杂性，层与层之间通过接口进行交互
- 分层的问题：引入额外开销，分层间可能隐藏了重要信息
- 计算机网络的经典分层
  - OSI模型（从上至下）：
    + 应用层（Application Layer）：通过应用层协议，提供应用程序便捷的网络服务调用
    + 表示层（Presentation Layer）（基本弃用）
    + 会话层（Session Layer）（基本弃用）
    + 传输层（Transport Layer）：将数据从源端口发送到目的端口（端对端管道，忽略了中间的网络转发）
    + 网络层（Network Layer）：将数据包跨越网络从源设备发送到目的设备
    + 数据链路层（Data Link Layer）：实现相邻网络实体间的数据传输
    + 物理层（Physical Layer）：信息物理传输

== TCP/IP 参考模型
  后于 TCP/IP 协议出现的技术 
  + 应用层（HTTP，域名，DNS，P2P......）
  + 传输层（TCP/UDP/IP，套接字......）
  + 互联网层
  + 网络接口层
  采用无连接技术
== 模型比较与问题
  - OSI：分层的实际实现糟糕，以至于从来没有真正被实现过，较为失败的技术。
  - TCP/IP：只基于TCP/IP协议，不足以用于新兴协议。
  - 有时双方的术语经常混用，不会明确区分（比如网络接口层称为数据链路层和物理层）
  本课程大体采用 TCP/IP 参考模型，但不局限于 TCP/IP 协议

== 协议封装
  每一层都有自己需要的头部，因此真正的数据是层层封装的，下层的头在上层看来也是数据
== 网络分层的实现
  - 端系统：实现全部功能
  - 边缘网和网络核心：第一层到第三层
    - 交换机：前两层，物理层和数据链路层，只能正确处理单跳传输
    - 路由器：交换机 + 网络层
    - 注：这是传统意义上的定义，现代交换机和路由器几乎已经不做区分
  - 特征
    - 复杂功能由端系统实现，聪明终端 + 简单网络，大大提升可拓展性
    - 以 IP 协议为核心：IP on everything, everything on IP
  - 局限性
    - IP 协议难以升级
    - _资源管理依赖端系统，网络核心只能进行粗粒度流量，而端系统之间又缺乏协同（排队延迟严重的原因之一）_

= 网络应用层
  事实上同一主机的程序间也可进行网络通信，但本门课程主要介绍不同主机间通讯
  - 应用层对传输层希望提供的服务：
    + 可靠传输
    + 高吞吐
    + 低时延
    + 安全
  - 实际传输层提供的服务
    + TCP
      - 面向连接
      - 可靠传输：丢包重传
      - 有序传输
      - 流量控制
      - 拥塞控制
      - 延迟、吞吐量、安全均无法保证
    + UDP
      - 无连接
      - 不可靠传输
      - 无法保证其他所有要求
      - 但由于协议简单，性能较 TCP 更好
  - 网络应用层的好处
    - 屏蔽底层细节：网络设备往往不在乎应用层逻辑
    - 抽象：许多网络应用有相同的通信模式，网络应用层封装了这些共同模式
    - 提供额外功能，如安全性
  例：TCP + SSL
    - TCP 明码传输，但 SSL 提供加密服务，保证隐私与数据完整
  == 端口
     由于主机上往往有多个应用层的实体（应用程序），因此通过端口的方式区分彼此
  
  == 客户端/服务器模式
    - 客户端向服务器发出请求
    - 服务器被动响应，必须始终在线并有固定IP地址与端口
    - 面向连接和无连接均可，面向连接模式的通讯是双向的
    - 服务器进程可以采用循环模式（也叫阻塞模式，多个请求时依请求的先后顺序依次响应）或者并发模式（也叫非阻塞模式，运行多个服务器进程，同时服务多个客户端）
    - 通常而言，不会使用无连接的并发模式，因为无连接UDP只有一个套接字，无法被多个从属进程同时访问
    - 特例： 浏览器/服务器模式

  == P2P 模式
    - 任何两个个体对等，多个主机间进行平等、对等的通信
    - 可以看作每个个体既是服务器也是客户端
    - 每个实体都不需要同时在线，可以随时进出，都贡献并收到一部分资源
    核心问题：索引，可能方法：
    + 中心化索引
    + 洪泛请求
    + 混合索引
    + 分布式哈希表

  == 应用层协议
    - 开放协议：所有使用开放协议的程序可以互操作，如 HTTP, DNS
    - 私有协议：厂商内部自行规定的协议，如微信、QQ
  == web 与 HTTP 协议
    - www = world wide web （万维网）
      由通过 urls 定位的 web 对象，http 服务器和客户端，服务器与客户端对话的 http 协议组成
    - url（统一资源定位符）
      协议类型：\//主机名:端口\//路径和文件名
    - web 对象
      - 静态对象和静态网页：多媒体内容，排版信息......（HTML，XML等标记语言）
      - 动态对象与动态网页：脚本，数据库......
        - CGI：通用网关接口
          - 一种在服务器创建动态文档的标准，定义了动态文档如何创建、输入输出结果如何交互等信息
          - 常见使用方式是通过环境变量传给 CGI 进程，再把 stdout 的结果返回客户端
  == HTTP 协议
    - 在传输层通常使用 TCP 80端口（HTTP 3.0改为 UDP）
    - 无状态协议，服务器不保留状态
    - HTTPS：HTTP + TLS
    === HTTP 1.0
      - 用户输入 URL
      - 若该页面包含两幅 Jpg 图像，则需执行三次完整的 TCP 连接（建立连接，数据传输，连接）
    === HTTP 1.1
      - 允许持久化连接
      - 之后允许 pipeline，一次发送多个请求，按顺序响应
    === HTTP 2
      - 多路复用，可以同时多任务交错，可以自定义优先级
      - 服务器端可以主动推送
      - 数据压缩
      - 允许应用进行流量控制
    === HTTP 3.0
      - 主要是将 TCP 换为 UDP + QUIC
    === HTTP 报文
      - 方法字段：最常用 get post
      - URL，使用 get 方法时可以带参数，往往有长度限制。使用 post 方法时参数放在实体主体中，此时参数可以加密
      - 响应报文会多一个状态码，均为三位数字
        - 1xx 表示通知信息
        - 2xx 成功
        - 3xx 表示重定向
        - 4xx 客户端发生差错，如请求中有方法错误或不能完成
        - 5xx 服务器端差错
    === wireshark
      网络监听工具，检测某个网卡的所有网络活动
    === HTTP 优化
      浏览器缓存：在浏览器主机保留用户访问过的服务器web副本\
      代理服务器缓存：ISP缓存ISP客户访问过的服务器副本，所有用户都可使用。\
      显然缓存技术需要检查网页是否过期，如果过期就返回新的对象。\
      现在往往使用询问式策略，在发送请求时给出指定缓存的时间
    === cookie
      http 协议无状态，用 cookie 将服务器和客户端的状态相互对应。
      但 cookie 技术也会造成一些隐私泄露问题

  == 电子邮件系统
    - 用户代理（邮件客户端）
      - 编辑发送邮件
      - 接收、读取和管理邮件
      - 管理地址
      - 无统一标准
    - 传输代理（邮件服务器）
      - 邮件在邮件服务器之间会通过 SMTP 协议发送。
      - 发送邮件时可以使用SMTP协议，接受时由于不能保证对方开机因此需要其他协议
    - SMTP协议：定义如何传输邮件，简单，无任何身份验证，无任何加密，传输ASCII码，效率较低
    - POP3, Post Office Protocol-version3/ IMAP, Internet Message Access Protocol，两种邮件访问协议，需要处理客户端不在线的问题
      - POP3：用户登录认证后，与服务器建立连接，收取后服务器更新（删除已收到的邮件）
      - IMAP：POP3 的改进版，允许保存、管理邮件
      - 两者都是基于 TCP 的应用层协议

    邮箱：邮件服务器上一段内存区域所保存的一个地址
  == 域名服务
    === DNS 简介
      - 现如今的域名服务完全是分布式的：
        - 域名映射记录多达数十亿条
        - 每天万亿级别的查询
        - 读操作远大于写操作
        - 对延迟敏感
      - 域名服务以树结构组织：
        - 顶级域名：com, net, cn,...
          - 一般分三类：国家及地区，互联网基础设施（ip6.arpa...），通用顶级域名
        - 二级域名：...
      - 域名服务器负责域名解析工作。如果没有相应结果，会向相邻的域名服务器查询，直到找到为止（这个过程与用户无关）
      - 根服务器：不负责直接查询，负责将用户的查询分发到顶级域名服务器
      - 二级域名服务器：将一定范围内的网络设备分为区和域
      - 本地 DNS 服务器：本地 ISP 提供的 DNS 服务器，离用户最近。

    === DNS 解析过程
      - 习惯上 UDP 53端口
      - 域名查询往往分为递归查询和迭代查询。往往本地 DNS 服务器采用递归查询，向更上级查询时习惯使用迭代查询。（请求方有一定自主权）
        + 递归查询：当收到一条无法处理的查询时，该域名服务器以客户身份向上级查询，直到得到结果（先向根服务器查询顶级域名，再依次向顶级域名服务器查询二级域名，直到得到结果）
        + 迭代查询：当收到一条无法处理的查询时，该域名服务器将更上级的域名服务器返回客户端从而降低根服务器负载
      - DNS 报文：
        - 事务 ID ：一个随机数，用于标识查询
        - 问题计数：DNS 查询的数目（可以同时多次请求，现实中基本只进行依次）
        - 回答计数：DNS 回答的数目
        - RD：递归查询标志，1 为（若服务器端允许）则递归查询，若为 0 且服务器支持则取决于递归结果是否得到权威应答。
        - RA：
        - Reply code：返回码，表示响应的差错状态
        - 问题部分
          - 查询名：一般是域名，有时也可反向查询
          - 查询类型：通常查询为 A，即查询域名对应的 IP 地址。通过 IP 查询域名的类型为 
        - 资源部分：
          - 回答问题区域字段
          - 权威域名服务器区域字段
          - 附加信息字段
          都使用资源记录格式（变长数组，自己记录自己的长度）
      
      === 优化：
        缓存：DNS 服务器会缓存查询结果，以提高查询效率\
        安全：原始的 DNS 服务没有任何加密和认证。
  == P2P
    每个实体都是一个对等结点，每个节点之间理论上可以互相连接，可以随时加入或退出。\
    理论上，这种模式可以充分利用带宽和计算资源。例如分发文件，单一服务器的带宽压力很大，而 P2P 模式下可以充分利用所有节点的带宽。\
    但是主要问题在于资源索引，也即给定资源，找到一个可用的提供资源的节点。
    === 可行的索引方式
    + 中心化索引：有一个中心化服务器负责检索
      可能问题：
      - 单点故障
      - 性能瓶颈
    + 洪泛请求：每个对等节点自己建立自己的索引，对等节点之间互相连接。互相连接的节点构成一个应用层面的图（一般将这种图称为 overlay 图），遍历所有节点找到所需资源
      可能问题：
        - 需要遍历图，对每个节点的计算压力很大
    + 混合索引：某些节点运算能力较强，记为超级节点。普通节点至少向超级节点连接，超级节点之间互相连接。普通节点向连接的超级节点寻求索引，超级节点之间洪泛请求。 
    === P2P 实例
    - Gnutella 协议：完全去中心化，纯粹的文件分发，采用洪泛请求但是需要假设一些节点始终存活
    - Bt 协议：不是纯 P2P 架构，所有正在交换某个文件的节点组成一个种子，依赖于中心化的跟踪器维护每个种子的信息
      优化策略：
      - 优先选择少见的文件块下载
      - 趋向于上传速度更多的节点，换言之贡献越多，下载越快
      - 往往设计策略能够激励节点留下来
      问题：
      - 下载速度不及预期
      - peer 缺乏共享精神
      - 恶意 peer 节点
      - 版权纠纷
      - 主流网站封锁
    - skype
      采用层次化的超级节点
    - 区块链
      频繁写操作，主要问题：如何决定写权力
    
    == 流媒体
      特点：
        - 任意方均读取写入
        - 延迟敏感，数据量大，主要传输视频或音频
        - 乱序数据完全失效
      视频编码标准：
        - H.264 最广泛，兼容性好
        - H.265 视频内容压缩更高，但硬件成本高且专利许可费高（提出时纳入了许多企业的专利，导致了很大的专利壁垒）
        - VP9、AV1 开源标准，性能也很好，但比较新使用较少
      音频编码标准：AAC、MP3、Opus等
      音视频封装容器格式：
        - MP4：兼容性好
        - MKV：允许多音轨、多字幕
        - FLV：早期由于跨平台常用，现逐渐淘汰
      目标：
        - 在网络条件有限的情况下保证传输质量
      === 媒体点播
        - 浏览器通过 HTTP 从服务器下载并播放流媒体文件
        - 发送端以恒定速率发送分包，但由于网络传输抖动，到达时速率非恒定。若到达即播放很容易发生卡顿
        - 常用策略是缓存一定时间后恒定速率播放，以时延为代价消除抖动性。
      === 主要的流媒体协议
        - 网络层：IP/RSVP（流媒体专用）
        - 传输层：TCP、UDP、SCTP
        - 流媒体技术：
          + RTP：建立在 UDP 的基础上，只负责数据传输，不做任何处理和服务质量保证
          + RTCP：与 RTP 配合使用，监事及反馈其服务质量，进行一些音视频同步等操作。这两个很少直接使用，往往作为基础
          + RTSP：本身不传输数据，是多媒体播放控制协议，负责暂停、继续等操作，记录和传输用户状态。结合RTCP使用，延迟大但开销低，用于摄像头，物联网等
          + RTMP：最早用于 FLASH，后来广泛使用。开销大，延迟低，支持复杂交互，广泛用于直播，实时通信等。   
          + RSVP 网络层协议，通常用于专网
          + WebRTC：建立浏览器间点对点传输
          + 基于 HTTP 的其他技术
            - MPEG-DASH：支持各种协议的开放标准，动态自适应传输，将完整视频拆分为固定时长的片段，每个片段采用不同码率，客户端自适应选取不同码率进行下载
            - HLS：APPLE 生态
            - HDS：本来用于 FLASH，后逐步停止更新     
      === 进一步优化
        使用一些传输友好的视频编码\
        适当放松丢包恢复\
        改进网络调度，进行边缘计算等
    == CDN 服务
      在互联网上，极少量网站拥有极大的流量，因此有了 CDN 来将互联网上的内容分发到不同位置，不同用户可以访问离自己更近的位置。\
      CDN 服务部署在广泛的地理分布，广度和深度较大，同时位置也要经由分析最大化效率。
      === 重定向
        CDN 网络需要实现将用户请求调度到临近 CDN 服务器
        - HTTP 重定向：服务提供者返回 CDN 清单，建议用户向新的位置发起请求
        - DNS 重定向：通过 DNS 服务器辅助重定向
        - 网页所有者直接重写页面，链接到 CDN 服务器
    == telnet
      早期的远程登陆服务，目标是解决异构计算机系统的差异性问题，尤其是对终端键入指令的解释
  == TFTP
    相比 FTP，协议更简单，建立在 UDP 之上，无目录操作。\
    利用接收方的每次确认来保证接收方确实收到，一段时间未收到确认则重传，接收方可能需要去重。\
  == SNMP
    主要用于管理计算机网络中的设备\
    指导思想：尽量简单。只定义了中心管理器进行的四类操作\
    操作方式：
      - 轮询：循环遍历所有设备
      - 陷阱：允许设备主动产生操作，类似于操作系统中的异常。开销较小，但对管理员要求较高。（需要提前定义异常事件）
    粒度粗糙，局限性很大。读操作只能获得一部分信息，写操作只能更改预先设置的一部分参数
= 网络传输层
  传输层的服务以尽力而为为目标，将复杂逻辑交由应用层实现。\
  最经典的传输层协议即为 UDP 和 TCP
  == UDP
    最简单的传输层协议，无连接，不可靠，无拥塞控制，无流量控制，无差错恢复，无时延保证，无安全保证，简单的错误检查。\
    发送单位为数据报文。
  == TCP
    可靠，面向连接，流量控制，拥塞控制，差错恢复，安全保证，复杂的错误检查。\
    发送单位为字节流。
  == 套接字
    无论 UDP 还是 TCP，都通过复用和分用，将套接字的数据交由网络设备，再由网络设备交给套接字。\
    传输层不处理分包等行为，交于更下层处理
    === TCP 套接字
      监听套接字：并不接收数据，只接收连接请求，一般只有一个，使用双方都知道的端口号
      连接套接字：接收数据，一般有多个，与监听套接字共享端口号。此时必须使用额外机制区分不同的套接字
    === UDP 套接字
      无连接，因此只有一个套接字，使用双方都知道的端口号\
      可选用有限纠错机制，主要任务是端口号的分用复用。\
      校验机制：计算 checksum
      一般实现时，发送方不设缓冲区，接收方设缓冲区。\
  == 可靠传输
    网络的可靠性是由端系统保证的，而不是网络设备。\
    网络设备有多种情况可以造成不可靠性，例如拥塞丢弃，不同路径导致后发先至。\
    OSI 模型中希望链路层提供可靠传输保障，但实际上大量可靠性由传输层甚至应用层实现，部分较新的技术在链路层或者网络层实现可靠性。\
    === 完美信道
      先从最简单情形开始，假设信道是完美的，不会丢包，不会出错等。此时可靠传输协议非常简单，只要忠实地发送数据接收数据即可。这样的协议有时称作乌托邦协议。
    === 有错但不丢包
      假设数据包传输过程中可能发生一些错误，这些错误可以被某种检错机制检查，但不会发生丢包问题。
      
      思想方法：自动重传请求
      - 发送方：发送数据包，等待确认，
      - 接收方：接收数据包，检查数据包是否有错，若有错则发送否定反馈，若无错则发送确认
      - 发送方：若收到确认，则发送下一个数据包，若收到否定反馈，则重传数据包

      实例：
        + rdt 2.0 协议：使用 NAK，ACK 作为否定、肯定反馈。这种协议称为停等协议，等到收到确认后才发送下一个数据包。

          问题：NAK,ACK 本身也可能损坏\
          解决方法：
            - 接收方再次反馈，以此类推。可能陷入死循环
            - 设计巧妙的校验技术，允许一定程度上恢复。可能带来额外的计算与传输开销
            - 发送方无法确认接收方状态时，直接进行重传。此时接收方需要去重处理
          现实中往往采用第三种情况，因为方案三只在发生错误时付出代价，而方案二则总是需要付出代价。在出错概率极高的网络中，有时使用类似方案二的技术更好。
        + rdt 2.1：采用重传技术的改进。发送数据包时需要序号，接收端需要适当丢弃
          - 由于 rdt 是停等协议，序号只需一个 bit 表明是否是之前数据的重传即可。
        
        + rdt 2.2：
          注意到采用此机制时，发送方准备接受确认时，只要没有确认信息完好（收不到反馈或者收到反馈有错），立刻重传即可。进而其实无需反馈有错，只需接收方在 ACK 中加入 seq，发送端收到回复时判断 seq 是否正确即可。
        
    === 可能丢包或出错
      这里不考虑乱序的问题。\
      在可能丢包的情境中，接收方可能不知道发送方是否发送了数据包，因此需要发送方自行处理。\
      + rdt 3.0 发送方采用超时重传，一段时间未收到确认就进行重传。此时也有接收方收到多次同一数据包的可能，因此需要接收方去重，但前面已经实现了去重机制。

      在停等协议之中，大量的时间被浪费在等待回复上，这是不必要的，可以进行优化：
    === 流水线传输
  
      多个数据包以流水线发送、接受。发送端依次发出，接收端接收后各自发送确认。每个等待确认的包都需要独特的序列号，发送方需要保存所有未被确认的数据包。此时若多个数据包出错，则每个数据包都需要重传。

      实践上，往往规定最大未确认包数量为 $N$，这被称为滑动窗口机制。有了滑动窗口，便可复用已经被确认收到的序列号。
      + 回退 $N$ 机制
        - 接收方对多个连续数据包进行累计确认，非连续数据包直接跳过。
        - 发送方维护计时器，从最古老计时器开始，若超时则重传该数据包及其后的所有数据包。
        - 该机制下，接收方只确认自己接收到包的数量，发送方的未确认序列一定是连续的，随接收方发送确认向后推移。
      + 选择重传机制
        - 接收方对每个数据包独立确认
        - 发送方对每个未确认数据包进行计数
        - 发送方超时或接收到 ACK 错误时，进行单个包的重传
        - 接收方接到乱序包时，对包进行缓存后重排
        - 接收方和发送方都维护一个窗口，窗口大小为 $N$。发送方接收到 sendbase 的 ACK 时，更新 sendbase。接收方收到：
          - $($recvbase, recvbase+ N - 1\ $\]$ : 确认 n 并缓存
          - recvbase : 确认 n，将一系列包交付应用，更新应用层
          - [recvbase - N, recvbase - 1]：再次确认 n （不能省略，否则由于 ACK 发生错误发送方的窗口可能卡住）
          - 其他：丢弃（可以确认发送方窗口已经滑过，因而不管也行）
        - 窗口大小不能超过 seq 取值的一半
        - 尽管机制复杂，确实仍有出错的可能：如果 pkg 1 延时过久才到达，可能会被认作新的 pkg 1。所幸实际使用中的 $N$ 往往非常大（TCP 使用 $2^31$），而网络中的包往往设计生命周期，因此这种情况发生的概率很小。
  == TCP 协议
    === 重要选项：
      + MSS 最大段长度：TCP 段的最大长度，一般为 1460 字节
      + 窗口比例因子：窗口大小的倍数，实际接收窗口大小 = 窗口大小 $* 2^("窗口比例因子")$
    === 可靠传输
      - TCP 协议中以字节流为基础，每次发送的数据包都是一段长度的字节
      - 基本机制与上面介绍的类似，采用流水线传输。不同的是它对字节建立序号，ACK 值给出下一个期望的字节序号，捎带在正常的数据包之中。
      - 定时器只对最早未被确认的字节进行计时，但重发时也之重发最早未确认的报文段。
      - 接收方采用累积确认，仅在按序正确收到报文段时向前推进
      - 但接收方对于失序的报文段也会缓存，以便后续重排
      + 一些优化
        - 超时值的确认可以利用 RTT 估计（数据包从发送到接收再返回的时间），可以用滑窗估计平均 RTT 值
          - 问题：ACK 可能是重传ACK，产生二义性。
          - 解决方法：计算 RTT 时忽略那些发生重传的数据包
          - 问题：发生重传的数据包往往是网络问题，一次到达的数据包往往是网络正常的情况，因此忽略重传数据包可能导致 RTT 估计偏小
          - 解决方案：采用超时补偿，一旦超时发生就翻倍超时值，直到某个给定上限
          - 实际使用中，在三次握手中估计初始 RTT，超时时进行补偿。
        - 快速重传
          在等待超时的过程中，我们与其闲置不如直接重传。\
          利用 ACK 机制，一旦受到重复的 ACK（规定为3次），发送方可以认为该包丢失，从而立即进行重传\
          事实上，现实中的大部分重传都发生在快速重传
        - 接收方
          理论上 TCP 协议并未规定接收方要进行缓存，但往往进行缓存\
          协议允许接收端推迟确认，也即接收若干报文段后进行累积确认。协议规定推迟确认时间最多 500ms，并且每隔一个报文段进行正常确认
    === 连接管理
      常规来想客户端服务器互相确认只需要两次握手，但实际上由于网络连接的不可靠性，只用两次握手可能会产生严重问题。

      因此，TCP 协议采用三次握手：
        - 客户端先向服务器发送连接请求，同时发送初始的字节序号（synbit = 1，ackbit = 0，seq = x）
        - 服务器端发送初始字节序号的同时，返回确认的 ACK（synbit = 1，ackbit = 1，ack = x+1，seq = y）
        - 客户端收到后，进行最后一次确认回返 ACK，此时客户端也可以顺便传输信息（synbit = 1, ackbit = 1, ack = y+1, seq = x+1）
      为了保证三次握手机制的正确，双方采用的序列号都必须在理想状态下对于不同的连接采用完全不同的序列号。实际上使用的是每 4ms 增加的 32 位数，基本可以满足需求。

      实际上在现实的网络中，传输速度已经越来越快，如果在网络服务中每秒发送超过 256kb 的数据便有可能发生回环，因此可能还会有其他机制。

      关闭连接时，采用 fin bit = 1。客户端和服务器四次握手，各自发送 fin，各自确认对方的 fin。双方发送完 fin 就不能再发送数据了，但还可以继续接受数据。\
      四次握手中，最后一个握手是不能被发送方确认的，因此会设计一个时延 timed_wait，等待对方是否重传。该时延往往设计为数据包在网络中最长寿命的二倍。

      注：有的时候如果客户端发送 fin 后服务器端也没有额外数据，四次握手的中间两次可以合并。
      
      异常处理方式：
        - 出现丢包时重传
        - 对方若提前下线，另一端将会不断重试，重试若干次失败后，可以选择直接放弃或者发送 reset ，再次再放弃。

      以上机制产生的一些安全隐患：
        - syn 洪泛攻击：
          服务器端第一次收到 syn 时便会分配资源准备连接，一段时间（通常 30s - 120s）后未收到后续才会放弃。因此攻击方可能使用大量虚假的 ip 地址发送大量的 syn 却不确认，耗尽服务器端资源。
    === 流量控制
      TCP 协议实现时，接收方会将接收到的数据缓存下来，上层应用程序可以不立刻取走。
      但由于不能确定应用程序何时取走（之前设计回退 n 和选择重传时，我们假定收到的数据立刻交付上一层，但 TCP 并不是这样） ，因此为了防止缓冲区被用满，必须设计一定流量控制机制。

      事实上，接收方时刻计算自己缓冲区的剩余大小并告知对方，对方不得发送超过此大小的数据。\
      特别的，如果剩余空间已经为零，对方必须停止发送。但是等到接收方有了空闲缓存，必须采用额外的机制告诉对方，这个额外机制称为零窗口通告。发送分收到对方已无空余缓存的信息时，必须不断发送零窗口探测报文段，询问对方是否有空余缓存。\ 
      零窗口探测报文采用计时器（称为坚持计时器），超时时便发送零窗口探测。

      但是这样的机制未必高效，接收方可能对数据的处理极其缓慢，导致每次创造的可用窗口都极小，浪费网络资源，这被称为糊涂窗口综合症。
      - 解决方法：
        + 接收方仅在窗口显著增加时才发送确认
        + 接收方发现缓冲窗口耗尽时手动采用推迟确认
        + 发送方积累足够多的数据再发送，但此时究竟累积多少并不好确认。例如使用 ssh 时，单次发送的数据量必然很小，此时再积累发送便会产生明显的时延。
      
      ==== Nagle 算法
        数据量大于一个 MSS 且窗口大小大于一个 MSS 时，发送方可以立刻发送数据。\
  
    === 拥塞控制
      拥塞控制是现代互联网非常重要的因素。拥塞控制的目的是管控数据的传输，防止超出网络的承载能力。\
      拥塞的原因：
        + 网络设备采取存储转发，一旦拥塞将会堆积大量数据包
        + 一旦数据包没有按时到达，发送方会进行重传，进一步加重拥塞
      
      早期的拥塞控制：在传输层中利用网络层提供的信息。这对网络层略显复杂，现代设计理念是尽量不让网络层做管理工作，交给端系统在传输层实现。

      - 发送方任务：
        - 感知网络的拥塞
          丢包意味着网络的不稳定，可以从丢包感知网络拥塞
        - 设计机制管理发送速率
          发送方使用拥塞窗口 cwnd 限制已发送未确认的数据量（实际使用中，它要与接收窗口的限制取最小值）
        - 采用合适的策略调节拥塞窗口
          + 乘性减策略：检测到丢包时直接减半，迅速降低缓解拥塞
          + 加性增策略：每经过一个 RTT（往返时间），增加一个 MSS，缓慢增加避免震荡
          实际实现上，RTT 难以测量，但原则是类似的：丢包（三个重复 ACK 或超时）时快速减少，正常时缓慢增加。分为以下三个步骤：
            + 慢启动：新建连接时以较小的窗口启动，起始速度 = $"cwnd"/"RTT"$

              这里由于起始速度很慢，没有必要缓慢增加，因此通常采用指数增加。

              理想状态下每个 RTT 增加，但是由于不好测量，实际实现上采取每个 ACK 增加的策略
            + 拥塞避免：慢启动一段时间后，进入拥塞避免阶段

              此时窗口已经很大，因此不宜使用指数增长，而是采用线性增长\
              区分慢启动与拥塞避免阶段利用阈值 ssthresh，当 cwnd < ssthresh 时，采用慢启动，否则采用拥塞避免。\
            
            + 当 cwnd 持续增大，最终会发生丢包：
              - 若收到三次重复 ACK ，说明虽然丢包，但网络还有一定传输能力
                - TCP Reno 中，进入快速恢复阶段：ssthresh 降低至 cwnd/2，cwnd 降低至 cwnd/2 + 3(MSS)，采用新机制调节 cwnd：
                  - 此时 cwnd 比 ssthresh 大3
                  - 若再次收到该 ACK，每收到一次将 cwnd 加一（注意到在 TCP 中，重复 ACK 说明中间有发生丢包，但是重复 ACK 越多说明丢包越少）
                  - 若收到新的 ACK，将 cwnd 降低至 ssthresh，进入拥塞避免阶段
                - TCP Tahoe 中，策略与下面超时情形相同，直接进入慢启动
              - 若超时，说明网络已经没有传输能力
                - TCP Reno 中，将 ssthresh 降低至 cwnd/2，cwnd 重置为慢启动初始值，重新慢启动
    === TCP 的公平性
      可以证明，TCP 利用的 AIMD 机制可以实现多个用户之间资源分配的公平性。严格来说，经过充分大的时间后，每个用户占有的带宽相等，且充分利用了总带宽。
    === 新型拥塞控制
      拥塞控制算法在过去的几十年中一直在发展，直到今日也是很热门的话题。主要的目标是提高网络的利用率，减少拥塞的发生。\
      现代大部分操作系统默认使用 cubic 作为拥塞控制算法。
      核心问题：
      + 端系统如何感知拥塞
      + 端系统如何应对拥塞

      慢启动阶段优化：主要依靠优化各个参数，例如 cwnd 在现代 linux 中往往设为 10 个 MSS，而不是 1 个 MSS。\

      ==== 拥塞控制优化
        + TCP New Reno
          在大约 1995 年形成标准，主要优化快速恢复阶段，同时丢多个包的问题。\
          - 发送方若收到 3 个重复 ACK，触发快速重传。如果只丢一个包，下一个 ACK 应当确认所有已发送包，否则称为 partial ACK。
            - 在 TCP Reno 中，收到 partial ACK 也会立刻进入拥塞避免阶段。
            - 而在 TCP New Reno 中，收到 partial ACK 时，不会立刻进入拥塞避免阶段，而是继续快速恢复阶段，继续补发之前丢的包。直到收到新的 ACK，才进入拥塞避免阶段。
          问题：每个 RTT 只能确认一个丢包
        + SACK （选择重传）
          - 握手时，双方确认是否支持 SACK
          - 在 SACK 中，多个丢包将在头部中一次返回（返回一个未收到的左闭右开区间）
        + BIC 算法
          核心思想：当时延带宽积较大时，Reno 的线性增长较为缓慢，不能充分利用资源。采用二分搜索的思想，快速确认合理的拥塞窗口。\
          具体思想：
          - 动态确认最大最小值 Wmax, Wmin。某次丢包时将 Wmax 调整至当前拥塞窗口大小，丢包后经过乘性减过程，成功收到重传确认报文，则将 Wmin 调整至当前拥塞窗口大小。
          - 查找时，每经过一个 RTT，未发生丢包则将窗口重置为 Wmin 和 Wmax 的中间值，并更新 Wmax 为当前窗口大小。若丢包，按照上述过程调整 Wmax 和 Wmin。
          - 为了防止意外，初始确认一个参数，Wmax 不能低于此值。
          - 若拥塞窗口达到 Wmax 还未丢包，按照之前二分查找过程的增长曲线，镜像的逐渐增加 Wmax

          优势：查找最优窗口的效率极高
          问题：对 RTT 极为敏感，若两个连接的 RTT 相差较大，则会导致严重的不公平
        + cubic

          采用三次曲线函数连续化，而不是二分搜索。\
        + TCP vegas
          在丢包之前就利用 RTT 值作为信号
        + TCP BBR
          适用于广域网，充分考虑瓶颈链路的拥塞情况
        + DCTCP
          适用于数据中心。数据中心中数据往往会有低时延高吞吐突发流量大的特点，需要特殊优化。
          特点：
          - 维持较低队列长度，采用标记策略使得丢包之前就感知拥塞
          - 短队列长度降低了排队时延
          - 精确调整窗口使得发送窗口变化平滑，不会吞吐量骤降
    === TCP 存在的问题
      + 大量策略在操作系统中决定，操作系统内核不能跟上网络技术的进步
      + 当代互联网加密往往基于 TLS，握手延迟严重
      + 队头阻塞，TCP 协议默认了包是有序的，但实际上许多场景下我们未必要保持有序，例如打开一个网页加载许多图片，一个图片丢包可能造成后面所有数据阻塞。
  == 新型传输层协议
    许多新型传输层协议的目标是在 UDP 的高效和 TCP 的稳定可靠上取折中
    == DCCP
      主要思想是在 UDP 上补充拥塞控制，从而可以利用在诸如网络游戏、流媒体之类容忍丢包但需要低时延的场景中。\
      在拥塞控制中，双方可能采取不同的拥塞控制机制
    == MPTCP
      高效利用现代端设备往往有多个网络设备的特点。
    == QUIC
      将可靠传输、拥塞控制、加密解密等机制于用户态实现，而不是内核态，摆脱操作系统的制约。
      - 无队头阻塞的多流复用
      - 明确的包序号和更精确的 RTT 
      - 快速握手，加密
      - IP 地址/端口切换无需重连，考虑移动端需求
      - 便于部署更新：同时也会产生大量 QUIC 版本同时可用，需要客户端与服务器之间进行版本协商。

        


]
#chapter1
