传输层
计算机网络
用户数据报协议 UDP
- UDP 是无连接的。
- UDP 尽最大努力交付。
- UDP 对交付下来的报文既不拆分也不合并。
- UDP 没有拥塞控制。
- UDP 支持一对一、一对多和多对多的交互通信。
- UDP 的首部开销小。

- 长度:UDP 用户数据报的长度,其最小值是 8。
- 检验和:检测 UDP 用户数据报在传输中是否有差错,UDP 的检验和是把首部和数据部分一起检验。UDP 用户数据报首部中的计算方法有些特殊,在计算检验和时需要加上 12 个字节的伪首部,检验之后再丢弃。
传输控制协议 TCP
特点
- TCP 在使用之前必须先建立 TCP 连接。
- TCP 是点对点的。
- TCP 提供全双工通信。
- TCP 面向字节流。

- 序号:TCP 连接中传送的每一个字节都按顺序编号,序号表示本报文段所发送的数据的第一个字节的编号。
- 确认号:期望收到对方下一个报文段的第一个数据字节的序号。
- 数据偏移:指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处的偏移量。
- 保留:保留为今后使用,目前置为 0。
- 紧急 URG:当 URG = 1 时,表明紧急指针字段有效,这个报文将不再按原来的排队顺序传输,而是尽快传输。
- 确认 ACK:在连接建立后所有传送的报文段都必须把 ACK 置为 1。
- 推送 PSH:当 PSH = 1 时,立即创建一个报文段,而不用等到报文段填满再传输。
- 复位 RST:当 RST = 1 时,表明 TCP 连接中出现严重错误,必须释放连接,然后再重新建立运输连接。
- 同步 SYN:当 SYN = 1 而 ACK = 0 时,表明这生死一个连接请求报文段。对方若同意建立连接,则在响应的报文段中使 SYN = 1 和 ACK = 1.
- 窗口:窗口值告诉对方对方允许发送的数据量,作为发送方设置发送窗口的依据。
- 校验和:在计算校验和时,需要在前面加上 12 字节的伪首部。
- 紧急指针:它指出紧急数据的末尾在报文段中的位置。
- 选项:长度可变。
可靠传输
停止等待协议
每发送完一个分组就停止发送,等待对方的确认,收到确认后再发送下一个分组。
接收方检测到分组出现了差错直接丢弃分组,什么都不做。
发送方对每一个发送的分组设置了超时计时器,超过时间没有收到确认就重传。
接收方收到重复的分组也要发送确认。
为了提高传输效率,可以采用流水线传输的方式,发送方可以连续发送多个分组。
连续 ARQ 协议
发送方需要维持一个发送窗口,发送方每接收到一个确认就把发送窗口向前滑动一个分组的位置。
接收方采用累计确认的方式,仅对按序到达的最后一个分组发送确认。
接收方可以在发送数据的时候将确认信息捎带上。
超时重传时间的选择
TCP 采用自适应算法,每一个报文段都会测量报文段的往返时间 RTT。当第一次测量时就将 RTTS 值设为这个 RTT 样本值,之后每一次测量到新的 RTT 样本都按照下式重新计算 RTTS。
标准建议 α 值为 0.125
超时重传的算法为
当发生重传时难以确定收到的确认是重传前还是重传后的确认,因此对于重传的确认不使用以上算法,而是取新的重传时间为旧的重传时间的 2 倍。
选择确认 SACK
当接收方收到不连续的数据块时可以仅对其中部分数据块发送确认,在确认中指出接收到的数据块的左右边界,左边界为第一个字节的序号,右边界为最后一个字节的序号减 1。
TCP 的流量控制
接收方在窗口字段可以对发送方的发送窗口大小进行限制。为了避免死锁,TCP 为每一个连接设有一个持续计时器,只要一方收到了零窗口通知,就启动持续计时器,当时间到期时就发送一个零窗口探测报文段,对方在发回的确认中给出现在的窗口值。
TCP 的拥塞控制
发送方维持一个叫拥塞窗口 cwnd 的状态变量,发送方的发送窗口不能够大于拥塞窗口。为了防止拥塞窗口变得过大,还需要设置一个慢开始门限 ssthresh。
慢开始
一开始设置 cwnd = 1,发送方每收到一个对新报文的确认就将 cwnd 增大 1,因此每经过一个传输轮次,拥塞窗口就会加倍。
当出现超时重传时,设置 ssthresh = cwnd/2,cwnd = 1 并且开始执行慢开始。
拥塞避免
当 cwnd 超过 ssthresh 就改为使用拥塞避免,拥塞避免中拥塞窗口按照线性规律增大。
快重传
接收方在接收到报文时要立即发送确认,即使收到了失序的报文段也要对已收到的报文段发送重复确认。
当发送方一连收到 3 个重复确认时就能够确定报文段丢失,然后立即重传。
快恢复
快重传表明只是个别报文段丢失,而不是发生了拥塞,因此快重传之后执行快恢复。
设置 ssthresh = cwnd/2,cwnd = ssthresh,并开始执行拥塞避免。

主动队列管理 AQM
旧的 AQM 为随机早期检测 RED,路由器需要维持两个参数,最小门限和最大门限。目前还没有标准的方法能够替代 AQM。
- 若平均队列长度小于最小门限,则把新的分组放入队列。
- 若平均队列长度大于最大门限,则把新的分组丢弃。
- 若平均队列长度在最小门限和最大门限之间,则按照一个丢弃概率 p 把新到达的分组丢弃。
TCP 的运输连接管理
TCP 建立连接需要经过三次握手。
- 客户端向服务器端发出连接请求报文段,然后进入 SYN-SENT(同步已发送)状态。连接请求报文段不能携带数据,但是需要消耗一个序号。
- 服务器端接收到连接请求报文段后,如同意建立连接,则发送确认报文段,然后进入 SYN-RCVD(同步已收到)状态。这个报文段不能携带数据,但是需要消耗一个序号。
- 客户端收到服务器端的确认后还要向服务器端给出 ACK 报文段,然后进入 ESTABLISHED 状态。ACK 报文段可以携带数据,如果不携带数据则不消耗序号。
- 服务器端收到确认后也进入 ESTABLISHED 状态。

TCP 释放连接需要经过四次分手
- 客户端先发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接,然后进入 FIN-WAIT-1(终止等待 1)状态。FIN 报文段即使不携带数据,也需要消耗一个序号。
- 服务器端收到连接释放报文段后发出确认,然后进入 CLOSE-WAIT(关闭等待)状态。
- 客户端收到确认后进入 FIN-WAIT-2(终止等待 2)状态。这时 TCP 连接处于半关闭状态,客户端已经没有数据需要发送了,服务器端发送的数据客户端仍然需要接收。
- 若服务器端已经没有需要发送数据,就发出连接释放报文段,然后进入 LAST-ACK(最后确认状态)。
- 客户端收到连接释放报文段后,必须对此发出确认。然后等待两倍 MSL(最长报文段寿命)再进入 CLOSED 状态,在此时间中可能收到来自服务器端的超时重传。
- 服务器端收到 ACK 报文段即进入 CLOSED 状态。
TCP 还设有一个保活计时器,服务器如果两小时没有收到客户的数据就发送一个探测报文段,之后每隔 75 秒发送一个探测报文段,如果一连发送 10 个探测报文段都没有收到响应,就关闭这个连接。