第3章:运输层

SyEic_L Lv4

1.概述和运输层服务

因特网运输层概述

  • UDP(用户数据报协议):不可靠
  • TCP(传输控制协议):可靠数据传输,提供拥塞控制

网络层中协议中的IP为主机间提供逻辑通信,IP是不可靠服务

2.多路复用与多路分解

一个进程有一个或多个socket,每个socket有位移标识符,标识符格式取决于它是UDP还是TCP

  • 多路分解:将运输层报文段中的数据交付到正确的socket的工作
  • 多路复用:从源主机从不同socket中收集数据块,并为每个数据块封装上首部信息从而生成报文段,然后将报文段传递到网络层

运输层多路复用要求:

  • socket有唯一标识符
  • 每个报文段有特殊字段来指示该报文段所要交付到的socket:这些特殊字段是端口号字段

无连接的多路复用和多路分解

源端口号与目的端口号的反转

面向连接的多路复用与多路分解

面向连接的多路复用与多路分解

3.无连接运输:UDP

  • 关于发送什么数据以及何时发送的应用层控制更为精细
  • 无须建立连接
  • 无连接状态
  • 分组首部开销小

流行因特网及其下面的运输协议

UDP报文段结构

UDP报文段结构

UDP检验和

用于确定当UDP报文段从源到达目的地移动时,其中的比特是否发生了改变

UDP必须在端到端基础上再运输层提供差错检测

4.可靠数据传输原理

可靠数据传输

可靠数据传输协议的下层协议也许是不可靠的 e.g. TCP是在不可靠的(IP)端到端网络层之上实现的可靠数据传输协议

经完全可靠信道的可靠数据传输:rdt1.0

最简单的情况:底层信道完全可靠

  • rdt_send是接受来自高层数据的事件
  • rdt_rcv是从底层接受一个分组的事件

rdt1.0

经具有比特差错信道的可靠数据运输:rdt2.0

基于重传机制的可靠数据传输协议称为自动重传请求协议(Automatic Repeat Request, ARQ)

  • 差错检测
  • 接收方反馈
  • 重传

rdt2.0

除非发送方确信接收方已正确接收当前分组,否则发送方将不会发送一块新数据,由于这种行为,rdt2.0这样的协议称为停等(stop-and-wait)协议

致命缺陷:ACK和NAK也可能受损

在数据分组中添加一新字段,让发送方对其数据分组编号,即将发送分组的序号放在该字段

对于停等协议,1比特序号足够

rdt2.1

rdt2.2

经具有比特差错的丢包信道的可靠数据传输:rdt3.0

需要一个倒计数定时器

发送方需要做到:

  • 每次发送一个分组(包括第一次分组和重传分组)时,便启动一个定时器
  • 响应定时器中断
  • 终止定时器

rdt3.0

rdt3.0运行

流水线可靠数据传输协议

rdt3.0性能问题核心在于是停等协议

流水线技术解决

  • 增加序号范围,每个输送中的分组必须有一个唯一的序号
  • 协议的发送方和接收方两端缓存多个分组
  • 解决流水线的差错恢复有两种基本方法
    • 回退N步(Go-Back-N, GBN)
    • 选择重传(Selective Repeat, SR)

停等和流水线发送

回退N步

Go-Back-N 模拟

  • 基序号(base)定义为最早未确认分组的序号
  • 下一个序号(nextseqnum)定义为最小未使用序号(即下一个待发分组的序号)
  • 窗口长度(N)

GBN中发送方看到的序号

GBN-FSM

GBN发送方必须相应的三种类型的事件:

  • 上层的调用:rdt_send()
    • 如果窗口未满: 产生一个分组并将其发送
    • 如果窗口已满:将数据返回给上层。隐式地指示上层该窗口已满,然后上层过一会再试
  • 收到一个ACK
    • 对序号为n的分组的确认采取累计确认的方式:表明接收方已正确接收到序号为n的以前且包括n在内的所有分组
  • 超时事件
    • 如果出现超时:发送方重传所有已发送但还未被确认的分组

GBN接收方:

  • 如果一个序号为n的分组被正确接收到,并且按序:则接收方为分组n发送一个ACK,并将该分组中的数据部分交付到上层
  • 其他所有情况:接收方丢弃该组,并为最近按序接收的分组重新发送ACK

运行中的GBN

选择重传

Selective Repeat 模拟

SR序号空间

发送方事件与操作:

  • 从上层收到数据
    • 如果序号位于发送方窗口内:则将数据打包并发送
    • 否则将数据缓存或返回给上层以便以后传输
  • 超时
    • 每个分组必须拥有其自己的逻辑定时器
  • 收到ACK
    • 如果收到ACK,且分组序号在窗口内:则发送方将那个被确认的分组标记为已接收
    • 如果分组序号等于send_base:则窗口基序号向前移动到具有最小序号的未确认分组处
    • 如果窗口移动了并且有序号落在窗口的未发送分组,则发送这些分组

接收方的事件与操作

  • 序号在[rcv_base, rcv_base+N1][rcv\_base, \ rcv\_base+N-1]内的分组被正确接收
    • 收到的分组落在接收方的窗口内:一个选择ACK被回送给发送方
    • 如果该分组以前没被收到过:则缓存该分组
    • 如果该分组的序号等于接受窗口的基序号(rcv_base):则该分组以前缓存的序号连续的分组交付给上层,然后,接收窗口按向前移动分组的编号向上交付这些分组
  • 序号在[rcv_baseN, rcv_base1][rcv\_base-N,\ rcv\_base-1]内的分组被正确收到
    • 必须产生一个ACK,即使该分组是接收方以前确认过的分组
  • 其他情况
    • 忽略该分组

SR操作

SR窗口和序号关系

窗口长度必须小于或等于序号空间大小的一半

5.面向连接的运输:TCP

TCP连接

TCP被称为是面向连接的,是因为在一个应用进程可以开始向另一个应用进程发送数据之前,这两个进程必须先相互“握手”,即它们必须相互发送某些预备报文段,以建立确保数据传输的参数

TCP连接提供的是全双工服务(full-duplex service):如果一台主机上的进程A与另一台主机上的进程B存在一条TCP连接,那么应用层数据就可在从进程B流向进程A的同时,也从进程A流向进程B

TCP连接也总是点对点的:即在单个发送方与接收方之间的连接

三次握手

  • 客户先发送一个特殊的TCP报文段
  • 服务器用一个特殊的TCP报文段来响应
  • 客户再用第三个特殊报文段作为响应(可以承载有效载荷)

一旦建立起一条TCP连接,两个应用进程之间可以相互发送数据:客户进程通过socket(该进程之门)传递数据流,数据一旦通过该门,它就由TCP控制,TCP将数据引导到发送缓存,接下来TCP不时从发送缓存中取出一块数据,并将数据传递到网络层

TCP从缓存中取出并放入报文段的数据数量受限于最大报文段长度(Maximum Segment Size, MSS),MSS通常根据最初确定的由本地发送主机的最大链路层帧长度(即所谓的最大传输单元(Maximum Transmission Unit, MTU))来设置

MSS是指在报文段里应用层数据的最大长度,而不是指包括首部的TCP报文段的最大长度

TCP报文段结构

TCP的首部一般是20字节:

  • 源端口号目的端口号

  • 检验和字段

  • 32bit的序号字段(sequence number field)和32bit的确认号字段(acknowledgment number field)

  • 16bit的接收窗口字段(receive window field):用于指示接收方愿意接受的字节数量

  • 4bit的首部长度字段(header length field):指示了以32bit的字为单位的TCP首部长度

  • 可选与变长的选项字段(options field)

  • 6bit的标志字段(flag field)

    • ACK:确认字段中的值是有效的
    • RST、SYN、FIN用于建立连接和拆除
    • PSH:接收方应立即将数据交给上层
    • URG:指示报文段里存在着被发送端的上层实体置为“紧急”的数据

TCP报文段结构

序号和确认号

一个报文段的序号(sequence number for a segment)是该报文段首字节的字节流编号

主机A填充进报文段的确认号是主机A期望从主机B收到的下一字节的序号

因为TCP只确认数据流中至第一个丢失字节为止的字节,所以TCP被称为提供累积确认(cumulative acknowledgment)

一条TCP连接的双方均可随机地选择初始序号,这样做可以减少那些仍在网络中存在的来自两台主机之间先前已终止的连接的报文段,误认为是后来这两台主机之间新建立连接所产生的有效报文段的可能性

往返时间(RTT)的估计与超时

估计往返时间

报文段的样本RTT(表示为SampleRTT)就是从某报文段被发出(即交给IP)到对该报文段的确认被收到之间的时间量。大多数的TCP的实现仅在某个时刻做一次SampleRTT测量,而不是为每个发送的报文段测量一个Sample RTT。这就是说,在任意时刻,仅为一个已发送的但目前尚未被确认的报文段估计SampleRTT,从而产生一个接近每个RTT的新SampleRTT值。另外,TCP绝不为已被重传的报文段计算SampleRTT

一旦获得一个新SampleRTT时,TCP就会根据下列公式来更新EstimatedRTT:

EstimatedRTT=(1α)EstimatedRTT+αSampleRTT EstimatedRTT = (1-\alpha) \cdot EstimatedRTT+ \alpha \cdot SampleRTT

给出的α\alpha推荐值是α=0.125\alpha=0.125

RTT偏差DevRTT,用于估算SampleRTT一般会偏离EstimatedRTT的程度:

DevRTT=(1β)DevRTT+βSampleRTTEstimatedRTT DevRTT=(1-\beta)\cdot DevRTT+\beta \cdot |SampleRTT - EstimatedRTT| β\beta的推荐值为0.250.25

设置和管理重传超时间隔

  • 超时间隔应该大于等于EstimatedRTT,否则将造成不必要的重传
  • 超时间隔不应该比EstimatedRTT大太多,否则当报文段丢失时,TCP不能很快地重传该报文段,导致数据传输时延大
TimeoutInterval=EstimatedRTT+4DevRTT TimeoutInterval = EstimatedRTT + 4 \cdot DevRTT

推荐的初始TimeoutInterval值为1秒。同时,当出现超时后,TimeoutInterval值将加倍,以免即将被确认的后继报文段过早出现超时。然而,只要收到报文段并更新EstimatedRTT,就使用上述公式再次计算TimeoutInterval

可靠数据传输

TCP在IP不可靠的尽力而为服务之上创建了一种可靠数据传输服务(reliable data transfer service)

TCP的可靠数据传输服务确保一个进程从其缓存中读出的数据流是无损坏、无间隙、非冗余和按序的数据流,即该字节流与连接的另一方端系统发送出的字节流是完全相同的

简化的TCP发送方

超时间隔加倍

大多数TCP实现中的一些修改:每当有超时事件发生时,TCP重传具有最小序号的还未被确认的报文段,只是每次TCP重传时都会将下一次的超时间隔设为先前值的两倍,而不是用EstimatedRTT和DevRTT推算出的值

快速重传

发送方通常可以在超时事件发生之前就通过注意所谓冗余ACK来较好地检测到丢包情况。冗余ACK(duplicate ACK)就是再次确认某个报文段的ACK,而发送方先前已经收到对该报文段的确认

当TCP接收方收到一个报文段但是其序号大于下一个所期望的、按序的报文段,它检测到了数据流中的一个间隔,这就是说有报文段丢失,此时它对已接收到的最后一个按序字节数据进行重复确认(即产生一个冗余ACK)

因为发送方经常一个接一个地发送大量的报文段,如果一个报文段丢失,就很可能引起一个接一个的冗余ACK。如果TCP接收到对相同数据的3个冗余ACK,它把这当作一种指示,说明这个已被确认过3次的报文段之后的报文段已经丢失,此时TCP就执行快速重传(fast retransmit)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
事件:收到ACK,具有ACK字段值y
if (y > SendBase){
SendBase = y
if (当前仍无任何应答报文段){
启动定时器
}
else{
对y收到的冗余ACK数加1
if (对y==3收到的冗余ACK数){
重新发送具有序号y的报文段
}
}
break
}

是回退N步还是选择重传

TCP与GBN有显著区别:许多TCP实现会将正确接收但失序的报文段缓存起来

对TCP提出的一种修改意见是所谓的选择确认(selective acknowledgment),它允许TCP接收方有选择地确认失序报文段,而不是累积地确认最后一个正确接收的有序报文段

流量控制

TCP为它的应用程序提供了流量控制服务(flow-control service)以消除发送方使接收方缓存溢出的可能性

流量控制是一个速度匹配服务,即发送方的发送速率与接收方应用程序的读取速率相匹配

TCP发送方也可能因为IP网络的拥塞而被遏制,这种形式的发送方的控制称为拥塞控制(congestion control)

TCP通过让发送方维护一个称为接收窗口(receive window)的变量来提供流量控制,接收窗口用于给发送方一个指示:该接收方还有多少可用的缓存空间

接收窗口用rwnd表示:

rwnd=RcvBuffer[LastByteRcvdLastByteRead] rwnd = RcvBuffer - [LastByteRcvd - LastByteRead]

接收窗口和接收缓存

TCP连接管理

客户中的TCP会用以下方式与服务器中的TCP建立一条TCP连接:

  1. 客户端的TCP首先向服务器端的TCP发送一个特殊的TCP报文段,该报文段不包含应用层数据。但是报文段的首部中的SYN被置为1,被称为SYN报文段。客户会随机选择一个初始序号(client_isn),并将此编号放置于该起始的TCP SYN报文段的序号字段中

  2. 包含TCP SYN报文段的IP数据到达服务器主机,服务器会从该数据报中提取出TCP SYN报文段,为该TCP连接分配TCP缓存和变量,并向该客户TCP发送允许连接的报文段,这个允许连接的报文段也不包含应用层数据,但是包含3个重要信息

    • SYN被置为1
    • 确认号字段被置为client_isn+1
    • 服务器选择自己的初始序号(server_isn),并将其放置到TCP报文段首部的序号字段中

    该允许连接的报文段被称为SYNACK报文段(SYNACK segment)

  3. 在收到SYNACK报文段后,客户也要给该连接分配缓存和变量。客户主机向服务器发送另外一个报文段,这最后一个报文段对服务器允许连接的报文段进行了确认,该报文SYN被置为0

完成3次握手(three-way handshake)之后,可以互相发送包括数据的报文段(SYN被置为0)

三次握手

一条TCP连接的两个进程中的任何一个都能终止该连接

假设某客户打算关闭连接:

  1. 客户应用进程发出一个关闭进程命令,这会引起客户TCP向服务器进程发送一个特殊的TCP报文段,这个特殊报文段的首部中的标志位FIN置为1,进入FIN_WAIT_1状态
  2. 服务器接收到该报文时,就向发送方会送一个确认报文段,客户收到后进入FIN_WAIT_2状态
  3. 然后,服务器发送它自己的终止报文段,其FIN被置为1,服务器进入LSAT_ACK状态
  4. 最后,该客户对这个服务器的终止报文段进行确认,进入TIME_WAIT状态

关闭TCP连接

客户TCP状态序列
三次握服务器TCP状态序列手

6.拥塞控制原理

拥塞原因与代价

情况1:两个发送方和一台具有无穷大缓存的路由器

拥塞情况1

  • 主机A和B向路由器提供流量的速率是λin字节/\lambda_{in}字节/秒
  • 在一段容量为R的共享式输出链路上传输

拥塞1函数

  • 每连接R/2R/2的吞吐量
  • 当发送速率接近R/2R/2时,平均时延就会越来越大,当发送速率超过R/2R/2时,平均排队分组数就会无限增长

情况2:两个发送方和一台具有有限缓存的路由器

当分组到达一个已满的缓存时会被丢弃,被发送方重传,用λin字节/\lambda_{in}字节/秒表示应用程序将初始数据发送到socket中的速率,运输层向网络中发送报文段(含有初始数据或重传数据)的速率用λin字节/\lambda_{in}'字节/秒表示,被称为网络的供给载荷(offered load)

情况2

  • a)主机A能够得知路由器中缓存是否空闲,只在空闲时才发送一个分组
  • b)发送方确定一个分组丢失时重传,平均角度说:0.333R字节/0.333R字节/秒是初始数据,0.166R字节/0.166R字节/秒是重传数据
  • c)发送方也许会提前发生超时并重传在队列中已被推迟但还未丢失的分组,当供给载荷接近R/2R/2时,其吞吐量将渐进R/4R/4

情况2函数

情况3:4个发送方和具有优先缓存的多台路由器及多跳路径

情况3

情况3函数

拥塞控制方法

  • 端到端拥塞控制
  • 网络辅助的拥塞控制

7.TCP拥塞控制

经典的TCP拥塞控制

运行在发送方的TCP拥塞控制机制跟踪一个额外的变量,即拥塞窗口(congestion window),表示为cwnd,在一个发送方中未被确认的数据量不会超过cwnd与rwnd中的最小值

LastByteSentLastByteAckedmin{cwnd,rwnd} LastByteSent-LastByteAcked \leq \min\{cwnd, rwnd\}

拥塞检测:当出现过度的拥塞时,在沿着这条路径上的一台(或多台)路由器的缓存会溢出,引起一个数据报被丢弃,丢弃的数据报接着会引起发送方的丢包事件(要么超时或收到3个冗余ACK),发送方就认为在发送方到接收方的路径上出现了拥塞的指示

TCP指导性原则:

  • 一个丢失的报文段表意味着拥塞
  • 一个确认报文段指示该网络正在向接收方交付发送方的报文段,因此,当对先前未确认报文段的确认到达时,能够增加发送方的的速率
  • 带宽探测

TCP拥塞控制算法:

  1. 慢启动
  2. 拥塞避免
  3. 快速回复

慢启动

当一条TCP连接开始时,cwnd的值通常初始置为一个MSS的较小值,这就使得发送速率大约为MSS/RTTMSS/RTT

在慢启动状态,cwnd的值以1个MSS开始并且每当传输的报文段首次被确认就增加1个MSS,TCP发送速率起始慢,但在慢启动阶段以指数增长

TCP慢启动

TCP将第二个状态变量的值ssthresh(慢启动阈值)设置为cwnd/2cwnd/2,即当检测到拥塞时将ssthresh置为拥塞窗口值的一半。当到达或超过ssthresh的值时,结束慢启动并且TCP转移到拥塞避免模式,TCP此时更为谨慎地增加cwnd,最后一种结束慢启动的方式是,如果检测到3个冗余ACK,这时TCP执行一种快速重传并进入快速恢复状态

TCP拥塞控制FSM

拥塞避免

一旦进入拥塞避免状态,cwnd的值大约是上次遇到拥塞时的值的一半

此时,每个RTT只将cwnd的值增加一个MSS,当出现超时时,cwnd的值被设置为1个MSS,当丢包事件(3个冗余ACK)出现时,ssthresh的值被更新为cwnd值的一半

快速恢复

  • 如果出现超时:cwnd被设置为1个MSS,ssthresh值设置为cwnd值的一半
  • 3个冗余ACK:Reno下,cwnd减到一半附近,然后线性增长

Tahoe-and-Reno

TCP拥塞控制:回顾

假定丢包由3个冗余的ACK而不是超时指示,TAP的拥塞控制是:每个RTT没cwnd线性增加1MSS,然后出现3个冗余ACK事件时cwnd减半

加性增、乘性减(Additive-Increase, Multiplicative-Decrease, AIMD)

加性增、乘性减

TCP CUBIC

Reno-and-CUBIC

对TCP吞吐量的宏观描述

窗口长度是ω\omega字节,当前往返时间是RTTRTT秒,则TCP发送速率大约是ω/RTT\omega/RTT

当一个丢包事件发生时,用WW表示ω\omega的值那么TCP的传输速率在W/(2×RTT)W/(2 \times RTT)W/RTTW/RTT之间变化

一条连接的平均吞吐量=0.75×WRTT 一条连接的平均吞吐量 = \dfrac{0.75 \times W}{RTT}

网络辅助明确拥塞通告和基于时延的拥塞控制

明确拥塞通告(Explicit Congestion Notification, ECN)

在网络层,有两个bit(4种可能的值)被用于ECN,位于IP数据报的服务类型字段中

  • 一种ECN bit设置指示该路由器正在历经拥塞,该拥塞指示由被标记的IP数据报携带,送给目的主机,再由目的主机通知发送主机
  • 另一种ECN bit设置通知路由器发送方和接收方是ECN使能的,因此能够对ECN指示的网络拥塞采取行动

明确拥塞通告

  • 00:Not-ECT,不支持ECN
  • 10:ECT(0)
  • 01:ECT(1)
  • 11:CE(Congestion Experienced)

基于时延的拥塞控制

在丢包出现之前主动检测拥塞

公平性

考虑K条TCP连接,每条都有不同的端到端路径,但是都经过一段传输速率为R bps的瓶颈链路,如果每条连接的平均传输速率接近R/KR/K,即每条连接都得到相同份额的链路带宽,则认为该拥塞控制机制是公平的

TCP公平性

  • 公平性和UDP
    • 运行在UDP上的多媒体应用是不公平的,因为他们不与其他连接合作,也不适时地调整其传输速率
  • 公平性和并行TCP连接
    • 当一个应用使用多条并行连接时,它占用了一条拥塞链路中较大比例的带宽
  • Title: 第3章:运输层
  • Author: SyEic_L
  • Created at : 2026-04-01 15:58:26
  • Updated at : 2026-04-01 16:52:00
  • Link: https://blog.syeicl.vip/2026/04/01/第3章:运输层/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments