开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
引言
这是 TCP 传输控制协议(初步)的第三篇,通过前两篇 ARQ和重传和分组窗口的介绍,我们对影响可靠性传输的问题有了大体的了解,接下来会详细介绍 TCP 协议,介绍 TCP 协议中如何保证可靠性传输以及给互联网应用程序提供什么类型的服务。
本章会对 TCP 的服务模型、可靠性以及头部和封装做初步的介绍,后续文章会依次对 TCP 的连接建立和结束、TCP 怎样估计每个连接的 RTT(往返时间估计,round-trip-time estimation)和基于这个估计设置超时重传、TCP 传输数据过程、窗口管理和流量控制、TCP 的拥塞控制算法、TCP 在保持没有连接时保持连接的活动性进行学习介绍。
TCP 服务模型
TCP 基于网络层(IPV4 或 IPV6),提供了一种面向连接(connection-oriented)、可靠的字节流服务。
TCP 提供一种字节流抽象概念给应用程序使用,其特点是不保留消息边界,如图所示:
按照 TCP/IP 协议族设计的端到端论点原则:涉及通信的应用程序或最终用户,其正确性和完整性才可能得到实现,即使为正确实现应用程序做了努力,其功能可能注定不会很完善。这个原则认为重要功能(例如差错控制、加密、交付确认)通常不会在大型系统的低层实现,所以 TCP 根本不会解读字节流里的字节内容,对字节流的解读取决于连接中的每个端点的应用程序。
TCP 中的可靠性
TCP 通过以下方式提供可靠性:
TCP 提供了一个字节流接口
组包(packetization):TCP 必须把一个发送应用程序的字节流转换成一组 IP 可以携带的分组。分组包含序列号,该序列号在 TCP 中实际代表了每个分组的第一个字节在整个数据流中的字节偏移,而不是分组号。这允许分组在传送中是可变大小的,并且允许它们组合,称为重新组包(repacketization)。应用程序数据被打散成 TCP 认为的最佳大小的块来发送,一般使得每个报文段按照不会被分篇的单个 IP 层数据报的大小来划分。
TCP 维持了一个强制校验和
TCP 维持了一个强制校验和,该校验和涉及它的头部、任何相关应用程序数据和 IP 头部的所有字段。这是一个端到端的伪头部,用于检测传送中引入的比特差错。
TCP 发送报文段通常设置一个重传计时器,等待对方确认接收
TCP 发送报文段通常设置一个重传计时器,等待对方确认接收,这个重传计时器不会为每个报文段设置,而是发送一个窗口的数据只设置一个计时器,当 ACK 到达时再更新超时。如果有一个确认没有及时收到,这个报文段就被重传。
TCP 使用的 ACK 是累积的
TCP 接收到连接的另一端数据时,可能不会立即发送确认,而是一般延迟片刻。TCP 使用的 ACK 是累积的,一个指示字节号 N 的 ACK 暗示着所有直到字节 N (但不包含 N)已经接收成功。
TCP 给应用程序提供一种双工服务
数据可向双向流动,两个方向相互独立,因此,连接的每个端点必须对每个方向维持数据流的一个序列号。双方相互发送 ACK 进行窗口告知以实现相反方向上的流量控制。
TCP 使用序列号
TCP 使用序列号,保证以有序的字节流传递给应用程序。
TCP 头部和封装
TCP 在 IP 数据报中的封装
如图所示,TCP 在 IP 数据报中的封装,TCP 头部紧跟着 IP 头部或 IPv6 扩展头部,经常是20字节长(不带 TCP 选项)。当带选项的话,TCP 头部可达 60字节。常见选项包括最大段大小、时间戳、窗口缩放和选择性 ACK。
TCP 头部
TCP 头部如图所示,它的标准长度是20字节,除非出现选项。头部长度(Header Length)字段以32位字位为单位给出头部的大小(最小值是5)。带阴影的字段(确认号(Acknowledgement)、窗口大小(Window Size)以及 ECE 位和 ACK 位)用于该报文段的发送方关联的相反方向上的数据流。
后续系列会对 TCP 的头部进行详细讨论。
资料来源
《TCP/IP 详解:卷1:协议》