One Sentence.

第十二章 TCP:传输控制协议(初步)

12.1 引言

  • 通信媒介可能会丢失或改变被传递的消息。——信息理论(information theory)& 编码理论(coding theory)

  • 如何使信息在通信信道中避免出错:

    • 使用差错校正码(某些比特的冗余)。
    • 尝试重新发送(自动重复请求,Automatic Repeat Request,ARQ)。

12.1.1 ARQ 和 重传

  • 如果不只考虑单个通信信道,而是几个的多跳级联。除了分组比特差错,还会有以下问题:

    • 分组重新排序。
    • 分组复制。
    • 分子泯灭。
  • 使用重发需要判断:

    • 接收方是否已收到分组。
    • 接收方接收到的分组是否与发送的一样。
  • 使用 ACK:

    • 发送方对一个 ACK 应等待多久。 (14章讨论)
    • 如果 ACK 丢失了怎么办。 (处理后续接收到的拷贝)
    • 分组收到了,但里面有错怎么办。(不发送 ACK)
    • 接收到重复的拷贝。(使用序列号)
  • 允许多个分组进入网络来提高吞吐量:引出窗口的概念。

12.1.2 分组窗口和滑动窗口

  • 分组窗口:已被发送方注入但还没完成确认的分组的集合。
  • 窗口大小:窗口中的分组数量。
  • 滑动窗口(sliding window)协议
  • 对发送方:哪些分组可被释放,哪些正在等待确认,哪些还不能发送。
  • 对接收方:哪些分组已被接收和确认,哪些是下一步期望的,哪些即使被接收也因限制而被丢弃。

12.1.3 变量窗口:流量控制和拥塞控制

  • 流量控制(flow control):接收方跟不上速度时强迫发送方慢下来。
  • 两种方式:

    • 基于速率(rate-based):适合流应用程序,可被用于广播和组播发现。
    • 基于窗口(window-based):窗口大小随时间变化。

    • 让接收方可以通知发送方使用多大的窗口,即窗口通告(window advertisement)或窗口更新(window update),一般和 ACK 是同一个分组携带的。

  • 拥塞控制(congestion control):中间网络出现瓶颈,而非接收方。

    • 明确(explicit)发信:使用窗口通告。
    • 隐形(implicit)发信:根据其他某些证据来决定放慢速度。

12.1.4 设置重传超时

  • 让协议实现尝试去估计,称之为往返时间估计(round-trip-time estimation)。

  • 选用一组 RTT 样本的均值,实际依然可能超过该值。

12.2 TCP 的引入

12.2.1 TCP 服务模型

  • TCP 提供了一种面向连接的(connection-oriented)、可靠的字节流服务。

    • 面向连接:交换数据前先建立连接。
    • 字节流:没有由 TCP 自动插入的记录标志或消息边界。每个端点独立选择自己的读和写大小。

12.2.2 TCP 中的可靠性

  • 组包(packetization):TCP 提供一个字节流接口,将一个发送应用程序的字节流转换成一组 IP 可以携带的分组。
  • 分组的序列号:分组第一个字节在整个数据流中的字节偏移,而不是分组号。这允许分组在传送中是可变大小的,允许重新组包(repacketization)。
  • 应用程序数据被打散成 TCP 认为的最佳大小的块来发送,一般使得每个报文段(由 TCP 传给 IP 的块,segment)按照不会被分片的单个 IP 层数据报的大小来划分。这和 UDP 每次写入整个数据不同。
  • TCP 根据校验和检测比特差错,如果报文段无效,会被直接丢弃。该校验可能不够强壮,应用程序应有自己的差错保护方法,或者使用一种中间层来达到同样的效果。
  • TCP 接收端可能对一个之前已经确认的报文段进行确认,以帮助发送方计算拥塞控制。
  • TCP 为发送的报文段设置重传计时器,实现自适应超时和重传策略。
  • ACK 的发送是累积的,收到字节号 N 的 ACK 暗示 N 之前(不包括 N)的字节都已经成功被接收了。
  • TCP 提供双工服务,数据可以在两个方向上平等地流动。每个端点都要为每个方向维持一个序列号、发送 ACK、实现流量控制。
  • TCP 会丢弃重复的报文段,记录乱序的报文段,保证不以杂乱的顺序交给应用程序数据。

12.3 TCP 头部和封装

  • TCP 头部的长度:20字节(无选项)~60字节。
  • 端口号:和 IP 地址组成套接字(socket)或称端点(endpoint)。每个TCP连接由一对套接字唯一地标识。
  • 序列号:标识了发送端到接收端代表着包含该序列号的报文段的数据中的第一个字节。到达 2^32-1 后再循环到 0。
  • 确认号(ACK):期待接收的下一个序列号。这个字段只有在 ACK 位被启用的情况下生效。通常会一直使用。

    • 虽然如此,现代 TCP 有一个选择确认(Selective ACKnowledgment,SACK)选项,允许告之发送方接收到了次序杂乱的数据。如果发送方支持选择重发(selective repeat),性能可得到明显改善。
  • SYN 位:客户端向服务器建立新连接发送第一个报文段时被启用。此时序列号字段包含了本次连接的这个方向上要使用的初始序列号(Initial Sequence Number,ISN,出于安全考虑,一般不从 0 或 1 开始)。

  • 头部长度:4位,20~60。
  • 8位的选项:一些老的实现只理解后6位。

    • CWR:拥塞窗口减(发送方降低发送速率)。
    • ECE:ECN 回显(发送方接收到一个更早的拥塞通告)。
    • URG:紧急(紧急指针字段有效,很少使用)。
    • ACK:确认。
    • PSH:推送(接收方应尽快给应用程序传送这个数据:没被可靠的实现或用到)。
    • RST:重置连接(连接取消,常因为错误)。
    • SYN:初始化序列号。
    • FIN:结束发送数据。
  • 窗口大小:16字节,最大 65535,但可利用窗口缩放选项进行扩大。实现流量控制,是一个字节数。

  • TCP 校验和。
  • 紧急指针(Urgent Pointer):一个必须要加到序列号字段上的正偏移,以产生紧急数据的最后一个字节的序列号。是一种发送方给接收方提供特殊标志数据的方法。
  • 最大段大小(MSS):指定发送方在相反方向上希望接收到的报文段的最大值。
  • 数据部分是可选的。