《计算机网络:自顶向下》

详细介绍了计算机网络中的核心概念,包括HTTP协议演进、DNS解析过程、视频流技术、TCP/UDP传输机制以及网络拥塞控制等重要内容。

网络概览

讲了一些网络的基本概念, 没什么干货

应用层

用于传达数据

web

http1

  • http1.0是短连接, 每次请求都要建立连接
  • http1.1是可持续链接, 一个连接可以发送多个请求(流水线)

虽然http1.1可以发送多个请求, 但是每个请求还是要等待上一个请求的返回, 不能并行发送请求, 就会有队头阻塞的问题, 意味着后面的请求要等待前面的请求返回后才能发送, 如果前面的请求非常耗时, 那么后面的请求就卡在那里了

http2

  • 二进制分帧, 因为这个技术才有了多路复用, 这个就是流的概念, 一个tcp链接中有多个流, 每个流有自己的id, 一个流就是一个请求, 每个流有不同的优先级
    • 成帧是指将数据分割成多个帧(frames),每个帧携带特定类型的信息。HTTP/2 中的帧是传输数据的基本单位,帧可以包含 HTTP 头部信息、数据负载、控制信息等。帧有不同的类型,例如:
      • HEADERS 帧:用于传输 HTTP 头部。
      • DATA 帧:用于传输实际数据负载。
      • PRIORITY 帧:用于传输优先级信息。
      • SETTINGS 帧:用于传输配置信息。
  • 响应报文的优先级
  • 服务器推送

http2 从http层面解决了队头阻塞的问题, 但是在传输层面还是有队头阻塞的问题, 因为http2是基于tcp的, 而tcp是有队头阻塞的问题的. 所以QUIC是基于udp的, 也就是说QUIC是基于http2的, 但是QUIC是基于udp的, 所以QUIC是没有队头阻塞的问题的

DNS

DNS的请求过程分为没有缓存和有缓存的, 一般来说讲没有缓存的会清楚一点

没有缓存的DNS请求

  1. 本地DNS服务器向根DNS服务器请求
  2. 根DNS服务器返回顶级域DNS服务器的地址
  3. 本地DNS服务器向顶级域DNS服务器请求
  4. 顶级域DNS服务器返回权威DNS服务器的地址
  5. 本地DNS服务器向权威DNS服务器请求
  6. 权威DNS服务器返回域名对应的IP地址
  7. 本地DNS服务器将IP地址返回给用户

有缓存的DNS请求

其中有浏览器缓存, 操作系统缓存, 本地DNS服务器缓存, 还有中间DNS服务器缓存, 每一个被命中的话, 就都会立刻返回.

视频流

http流

Youtube用的就是这种, 由用户选择码率.

DASH流(Dynamic Adaptive Streaming over HTTP)

Netflix用的就是这种, 由服务器选择码率.

CDN

一般传输视频都要使用CDN, 有时候CDN会根据用户的地理位置选择最近的服务器, 有时候会根据用户的网络情况选择最快的服务器.

有了CDN后的DNS请求过程是

  1. 本地DNS服务器向根DNS服务器请求
  2. 根DNS服务器返回CDN的域的主机名(一般是域名)
  3. 本地DNS服务器向CDN的域的主机名请求
  4. CDN的域的主机名返回CDN的一台主机的IP地址
  5. 用户请求这个IP地址

运输层

这一层存在的意义是保证数据的传输安全

同时运输层也有多路复用和多路分解, 因为传输的是一根线, 但不同应用是不同端口, 所以要有多路复用和多路分解

UDP

UDP的数据包格式在这里有阐述, 里面有校验和, 别的就都没有了, 只能判断出来数据包是否损坏, 不能判断出来数据包的顺序是否正确, 也不能判断出来数据包是否丢失

可靠数据传输

  • 流水线
  • 滑动窗口
    • 快速交付, 窗口过去的就可以交付到应用层
  • 回退N步(GBN)
    • 必须按照顺序来接收数据包, 如果不按照顺序来接收数据包, 那么就会丢弃这个数据包
    • 比如说接收到了1, 2, 3, 5, 6, 7, 那么就会丢弃5, 6, 7, 然后重发5, 6, 7
  • 选择重传(SR)
    • 可以接收乱序的数据包, 但是只能接收一次, 如果重复接收, 那么就会丢弃这个数据包
    • 比如说在一个窗口内有4块数据包, SR会记录哪些是被接收的, 哪些是没有被接收的, 如果没有被接收, 那么就会重发这个数据包

TCP

tcp结合了GBN和SR的优点, 既可以接收乱序的数据包, 又可以重发数据包.

SYN Flood 攻击

SYN Flood攻击是一种DoS攻击, 攻击者向服务器发送大量的SYN包, 服务器会为每一个SYN包分配一个资源, 但是不会为这个资源分配一个线程, 所以服务器会很快耗尽资源, 无法再接受新的连接, 我觉得这也是nmap扫描的原理, 但是nmap扫描是为了获取服务器的信息, 而SYN Flood攻击是为了耗尽服务器的资源.

解决方法是SYN Cookies:

  1. 收到 SYN 包:当服务器收到一个 SYN 包时,不分配资源,也不在半连接队列中记录状态。
  2. 计算 syncookie:服务器根据客户端的 SYN 包内容(如客户端的初始序列号和其他TCP头部信息)以及一个秘密的服务器密钥计算一个加密的值,称为 syncookie。
  3. 发送 SYN-ACK 包:服务器在 SYN-ACK 包中使用这个 syncookie 作为初始序列号(seq),并发送回客户端。
  4. 收到 ACK 包:当服务器收到客户端的 ACK 包时,服务器通过解码 ACK 包中的序列号,检查这个序列号是否与预期的 syncookie 匹配。如果匹配,说明这是一个合法的连接请求。

我当初看的时候有一个困惑, 就是为什么要用cookies记录状态, 后来我才发现, 你就算不用cookies记录状态, 服务器在分配资源的时候也会记录客户端发来的seq, 来确保下一个数据包是不是和上一个数据包是同一个连接.

拥塞控制

  • 慢启动
    • 一开始发送的数据包很少, 然后每次收到一个ACK包, 就会增加发送的数据包的数量
  • 拥塞避免
    • 一旦发送的数据包的数量超过了一个阈值, 就会减少发送的数据包的数量, 每次加1
  • 快速重传
    • 如果发送的数据包超时了, 就会重发这个数据包
      • 不要等待自己发送数据时进行捎带确认, 而是立即发送确认
      • 已经收到失序的数据包也要重复确认
      • 收到三个重复的ACK包, 立即重传
  • 快速恢复
    • 一旦收到三个重复的ACK包, 就会减少发送的数据包的数量, 但是不会减少到慢启动的阈值, 而是减少到慢启动的阈值的一半, 然后进入拥塞避免

网络层:数据平面

使用 Hugo 构建
主题 StackJimmy 设计