TCP/IP协议栈中,TCP和UDP属于传输层,负责实现数据的传输.
其中TCP是面向连接的和基于单个字节流的/保证顺序的可靠传输协议,UDP是无连接的/不可靠的/面向报文的协议.两者的报文格式如下所示
最后的数据报在网络层添加上 IP 头部信息之后封装成数据包, 通过路由从源主机传输到目标主机
其中 UDP 只有 8 字节的报文头部, 也只记录了源端口目的端口, 当数据包从网卡发送出去之后可能损坏, 可能丢包, 可能乱序, 发送方只负责将这个数据包发送出去, 只是一种 "尽力而为" 的策略, 至于接收方如何, 是否收到, 是否还有能力(缓冲区)接收, 是否乱序都不是 UDP 协议负责的内容;
TCP 的报文虽然也可能出现上述损坏丢包乱序这些问题, 但在数据包头部额外添加了 "序号" 和 "确认号" 用于确认数据包到达, 一些数据位(例如 SYN ACK FIN)用于确认通信双方状态, 窗口大小用于流量控制, 因此在传输层实现了可靠传输;
TCP 协议与包括 UDP 在内的其他传输层协议的主要差别在于:数据传输质量 .UDP 协议将数据发送出去之后就不管了,但 TCP 还会对已发送的数据进行跟踪,以防丢失.这样就有效地实现了 TCP 协议的两个关键特性:
为实现这两个设计目标,TCP 协议引入了所谓的 滑动窗口( sliding window )机制, 除此之外 TCP 还有流量控制和拥塞控制的手段
流量控制(Flow Control):
拥塞控制(Congestion Control):
由于 IP 协议缺乏反馈机制,为保证可靠性,TCP 协议规定:当接收方收到一个数据后,必须回复 ACK 给发送方.这样发送方就能得到反馈,如果数据发出去后很长时间都没有收到 ACK 确认,说明数据很有可能已经丢失了.
一旦数据在传输过程中丢失,发送方必须重传.因此,TCP 每次发送数据后,都会启动一个定时器.如果定时器超时还没收到对方确认,TCP 就会重新发送数据.由于 IP 协议缺乏反馈机制,为保证可靠性,TCP 协议规定:当接收方收到一个数据后,必须回复 ACK 给发送方.这样发送方就能得到反馈,如果数据发出去后很长时间都没有收到 ACK 确认,说明数据很有可能已经丢失了.
TCP使用累积确认机制,表示接收方已成功收到并按序处理了截至确认序号的所有字节.如果接收方成功收到序号为X的数据,那么它将发送一个确认序号为X+1的确认消息,表示它已经准备好接收从X+1开始的数据.
选择确认是TCP的一种扩展机制,允许接收方在确认中明确指定已成功接收的数据块范围,而不仅仅是最后一个累积确认的序号.这提高了对丢失或重复数据的处理能力.
延迟确认是指接收方不立即发送确认,而是等待一段时间,看是否有更多的数据需要一起确认.这可以减少确认消息的数量,提高网络利用率.
紧急确认用于处理TCP紧急数据.如果接收方收到带有紧急标志的TCP数据,它会立即回复一个紧急确认,通知发送方已经成功接收了紧急数据.
SSH ctrl+C 启用紧急指针, 中断正在进行的操作, 优先处理, 快速响应
接收缓冲区大小是有限的,如果应用进程处理缓慢,发送方还拼命发送,最终肯定会压垮接收方.因此,当缓冲区有变化时,接收方应该通过 窗口大小 字段,将它的剩余大小告知发送方.
接收方通告的窗口大小通常称为 通告窗口( advertised window ),可缩写为 awnd .它起到约束发送方发送速度的作用:
通过通告窗口,发送方可以实时感知接收方缓冲区的状态,然后根据缓冲区剩余空间动态调整发送速度,这就是 TCP 的 流量控制( flow control )机制.
我们希望 TCP 能够根据网络链路的实时状态,自动调整发送速度,这就是 TCP 协议的 拥塞控制( congestion control )机制.拥塞控制机制细节很复杂,但原理却出奇的简单:
方法: