计算机网络自顶向下 第3章 运输层
3.1 概述和运输层服务
- 作用:为运行在不同主机上的应用进程之间提供了逻辑通信(logic communication)功能。
- 在运输层的分组称为运输层报文段(segment),
3.1.1 运输层和网络层的关系
- 网络层提供了主机之间的逻辑通信。
- 运输层为不同主机上的进程提供了逻辑通信。
3.1.2 因特网运输层概述
- UDP(用户数据报协议):为应用程序提供了一种不可靠、无连接的服务。
- TCP(传输控制协议):为应用程序提供了一种可靠的、面向连接的服务。TCP还提供如下的附加服务:
- 可靠数据传输(relable data transfer):通过使用流量控制、序号、确认和定时器确保正确地、按序地将数据从发送进程交付给接收进程。
- 拥塞控制(congestion-control):TCP力求为每个通过一条拥塞网络链路的连接平等地共享网络链路带宽,通过调节TCP连接发送端发送进网络流量速率来实现。
- 将主机交付扩展到进程间交付被称为运输层的多路复用(transport-layer multiplexing)与多路分解(demultiplexing)。
3.2 多路复用与多路分解
-
将运输层报文段中的数据交付到正确的套接字的工作称为多路分解(demultiplexing)。
-
在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息生成报文段,然后将报文段传递到网络的工作称为多路复用(multiplexing)。
-
为了实现上述功能,使用源端口号字段(source port number field)和目的端口字段(distination port number field)。
- 端口号是一个16比特的数,大小在0~65535之间。
- 0~1023的端口号称为周知端口号(well-known port number),保留个HTTP和FTP等协议使用。
1.无连接的多路复用与多路分解
一个UDP套接字是由一个二元组来标识,包括一个目的IP地址和目的端口号。
2.面向连接的多路复用与多路分解
TCP套接字是由一个四元组(源IP地址、源端口号、目的IP地址、目的端口号)来标识的。这是因为TCP要保存连接状态。
3.Web服务器和TCP
没内容
3.3 无连接运输:UDP
-
UDP(User Datagram Protocol) 只是做了运输协议能够做的最少工作。包括:
- 复用/分解功能
- 少量的差错检测
-
UDP相比TCP的优点:
- 使用UDP的应用也可以实现可靠数据传输,通过应用层来实现,比如在应用程序中增加确认与重传机制等。
- 速度更快。
- 无需建立连接。
- 不用进行拥塞控制。
- 分组首部开销小,UDP近由8个字节,而TCP由20个字节的首部开销。
-
流行的因特网应用及其运输层协议
| 应用 | 应用层协议 | 下面的运输层协议 |
|---|---|---|
| 电子邮件 | SMTP | TCP |
| 远程终端访问 | Telnet | TCP |
| Web | HTTP | TCP |
| 文件传输 | FTP | TCP |
| 远程文件服务器 | NFS | 通常UDP |
| 流式多媒体 | 通常专用 | UDP或TCP |
| 因特网电话 | 通常专用 | UDP或TCP |
| 网络管理 | SNMP | 通常UDP |
| 路由选择协议 | RIP | 通常UDP |
| 域名系统 | DNS | 通常UDP |
3.3.1 UDP报文段结构

3.3.2 UDP检验和
- UDP检验和,通过对UDP报文中的所有16比特字的和进行反码运算,注意在求和时,如果最高位有溢出要进行回卷(即将最高位溢出的结果加到最低位)。
- 在接收方,对所有数据求和的结果将是1111111111111111(因为是数据和加上其反码)。如果有一个比特为0,标识数据出现差错。
3.4 可靠数据传输原理
- 可靠数据传输协议(rliable data transfer protocol)的责任是保证传输数据比特不会受到损坏或丢失,而且所有数据都是按照其发送顺序进行交付。
- 用rdt表示可靠数据传输。
- 用udp标识不可靠数据传输。
3.4.1 构造可靠传输协议
参考可靠传输协议…
1.经完全可靠信道的可靠数据传输:rdt 1.0

- rdt的发送端通过rdt_send(data)事件来接受较高层的数据,产生一个包含该数据的分组packet(通过make_pkt(data)),并将该分组发送到信道上去。
- 在接收端,rdt通过rdt_rcv(packet)事件从底层信道接收一个分组,并从分组中抽取收据(通过extract(packet,data)动作),并将数据上传给较高层(通过deliver_data(data))动作。
- 由于信道完全可信,所以直接发送数据,而不需要任何反馈。
2.经具有比特差错信道的可靠数据传输:rdt 2.0
- rdt2.0在rdt1.0的基础上解决了比特位翻转的问题
- 底层信道实际上可能会在分组中出现比特受损。
- 在计算机网络中,基于重传机制的可靠数据传输协议称为自动重传请求(Automatic Repeat reQuest,ARQ)协议。
ARQ还需要另外三种协议功能来处理比特差错:
- 差错检测
- 接收方反馈:比如用0标识NAK(否定确认) 和用1表示ACK(肯定确认)
- 重传

但是rdt2.0有着一个致命的缺点,只考虑了发送方到接收方的数据传输,如果反馈信息ACK,NAK传输时发生比特位翻转会出现什么情况?如果ACK发生翻转,那么发送方会再次重复的发送相同的数据包;如果NAK发生翻转,那么发送方会认为数据传输情况很好,但是接收方却已经收到了一个错误的数据包。(因为ACK可能会错误,因此多了两个状态)
由此rdt2.1应运而生,在rdt2.0的基础之上,发送方在打包数据包时添加了0或者1编号,同样ACK,NAK字段上也添加了0,1字段,表示0.1号字段的确认或者否定。发送方就有了2种状态发送0号数据包,1号数据包,接收方也有了2种状态等待0号数据包和等待1号数据包。现在假设情景发送方向接收方发送0号数据包,如果接收方接收到0号数据包,返回ACK,但是ACK出现翻转,接收方处于等待1号数据状态,发送方重复发送0号数据,接收方会拒绝0号数据,避免重复。如果接收方接收到0号数据包出现错误,返回NAK,但是NAK出现翻转,接收方处于等待0号数据状态,发送方继续发送1号数据,接收方会拒绝1号数据,避免错序。


rdt2.2是在rdt2.1上的基础之上做了小小的改善,摒弃了NAK,只需采用ACK。我们在ACK的信息上加上了期望的顺序号,现在假设情景发送方向接收方发送0号数据包,如果接收方接收到0号数据包,返回(ACK,1),发送方接着发送1号数据包。如果接收方接收到0号数据包出现错误,返回(ACK,0),发送方重传0号数据包。


3.经具有比特差错的丢包信道的可靠数据传输:rdt 3.0
- 基于rdt2.2中的技术(检验和、序号、ACK分组和重传等)需要增加一种新的协议解决丢包问题。
- 为了实现基于时间的重传机制,需要一个倒计数定时器(countdown timer),在一个给定的时间过后,可中断发送方。因此需要做到
- 每发送一个分组时,启动一个定时器。
- 响应定时器中断。
- 终止定时器。


3.4.2 流水线可靠数据传输协议

流水线(pipelining)技术可能给可靠传输协议带来如下影响:
- 必须增加序号范围:每个分组都有唯一的序号,
- 接收方和发送方可能需要缓存多个分组。
- 解决流水线的差错恢复的两种基本方法:回退N步(Go-Back-N,GBN)和选择重传(Selectinve Repeat,SR)。
3.4.3 回退N步
在回退N步中,允许发送方发送多个分组而不需等待确认。最大允许数为N。N常被称为窗口长度(window size),GBN协议也常被称为滑动窗口协议。
- 基序号(base):为最早的未确认分组的序号。
- 下一序号(nextseqnum):为最小的未使用的序号

GBN发送方必须相应三种类型的事件:
- 上层的调用:当上层调用rdt_send()时,要检测发送窗口是否已满。如果未满,产生一个分组发送。如果满了,返回数据给上层,然后上层可能过一会儿再试。
- 收到一个ACK。在GBN协议中,对序号为n的分组的确认采取累积确认(cumulative acknowledgment)的方式,表明接收方已正确收到序号为n的以前且包括n在内的所有分组。
- 超时时间。如果出现超时,发送方重传所有已发送但还未被确认的分组。
GNB接收方则按序接受分组,其他情况则丢弃该分组。

3.4.4 选择重传
- 在GBN中,单个分组的差错能够引起GBN重传大量分组。
- 选择重传(SR)协议通过让发送方仅重传那些它怀疑在接收方出错的分组而避免不必要的重传。

可靠传输机制及其用途的总结
| 机制 | 用途和说明 |
|---|---|
| 检验和 | 用于检测一个传输分组中的比特错误 |
| 定时器 | 用于超时/重传一个分组 |
| 序号 | 用于对从发送方流向接收方的数据分组按顺序编号,可以让接收方检测出丢失或冗余的分组 |
| 确认 | 接受方用于告诉发送方一个分组或一组分组已被正确地接收到了 |
| 否定确认 | 接收方告诉发送方某个分组未被正常地接收,通常带着该分组的序号 |
| 窗口、流水线 | 将发送方发送数据报范围限定在一个范围内的分组,流水线用来增加发送方信道利用率 |
3.5 面向连接的运输:TCP
3.5.1 TCP连接
- TCP是面向连接的(connection-oriented)
- TCP连接提供的是全双工服务(full-duplex service):即通信双发都可以收发信息。
- TCP连接是点对点(point-to-point)的,所谓多播在TCP中是不可能的。
- TCP会将数据引导到该连接的TCP缓存(sender buffer)里,之后就会时不时地从缓存中取一块数据发送。
- TCP可以从发送缓存取出并放入报文段中的数据数量受限于最大报文长度(Maximum Segment Size,MSS)。MSS根据本地主机发送的最大链路层帧长度(即最大传输单元(Maximum Transmission Unit,MTU))设置。

3.5.2 TCP报文结构

除了源端口和目的端口,TCP首部也包含检验和字段(checksum field)。
- 32比特的序号字段(sequence number field)和32比特的确认号字段(acknowledgment number field)。用来进行可靠数据传输服务。序号是对应报文段首字节的字节流编号。确认号即为当前累计已收到的数据报首字节序号+长度+1(比如收到一个0 ~ 535和一个900 ~ 1000的包,返回的序号是536)。
- 16比特的接收窗口字段(receive window field),该字段用于流量控制,指示接收方愿意接受的字节数量。
- 4比特的首部长度字段(header length field),该字段指示了以32比特的字为单位的TCP首部长度。
- 可选与边长的选项字段(options field),该字段用于发送方与接收方协商最大报文长度(MSS)时,或在高速网络环境下作窗口调节因子时使用。
- 6比特的标志字段(flag field)。ACK比特用于指示确认字段中的值是有效的。RST、SYN和FIN比特用于连接建立和拆除。当PSH比特被设置的时候,就指示接收方应立即将数据交给上层。最后URG用来指示报文段里存在着被发送端的上层实体设置为 “紧急” 的数据,紧急数据的最后一个字节由16比特的紧急数据指针字段指出。
3.5.3 往返时间的估计与超时
TCP采用超时/重传机制来处理报文段的丢失问题。因此超时间隔必须大于该连接的往返时间(RTT)。
1.估计往返时间
-
TCP使用样本估计往返时间。报文段的样本RTT(表示为SampleRTT)就是从某报文段被发出到对该报文段的确认被收到之间的时间两。
-
TCP维持一个SampleRTT均值(称为EstimatedRTT)来对抗路由器的拥塞和端系统负载的变化。
E s t i m a t e d R T T = ( 1 − α ) ⋅ E s t i m a t e d R T T + α S a m p l e R T T EstimatedRTT = (1-\alpha )\cdot EstimatedRTT + \alpha SampleRTT EstimatedRTT=(1−α)⋅EstimatedRTT+αSampleRTT
这种平均通常为称为指数加权移动平均(Exponential Weighted Moving Average,EWMA)。在这里 α \alpha α的建议值为0.125。 -
除了估算RTT,测量RTT的变化也是有价值的,RTT变差DecRTT如下, β \beta β的推荐值为0.25。
D e v R T T = ( 1 − β ) ⋅ D e v R T T + β ⋅ ∣ S a m p l e R T T − E s t i m a t e d R T T ∣ DevRTT = (1-\beta)\cdot DevRTT + \beta \cdot |SampleRTT - EstimatedRTT| DevRTT=(1−β)⋅DevRTT+β⋅∣SampleRTT−EstimatedRTT∣
2.设置和管理重传超时间隔
- 超时间隔TimeoutInterval为
T i m e o u t I n t e r v a l = E s t i m a t e d R T T + 4 ⋅ D e v R T T TimeoutInterval = EstimatedRTT+4\cdot DevRTT TimeoutInterval=EstimatedRTT+4⋅DevRTT
3.5.4 可靠数据传输
-
TCP在IP不可靠的尽力而为的服务之上创建了一种可靠数据传输服务(reliable data transfer service)。确保一个进程从其接受缓存中读出的数据流是无损坏、无间隔、非冗余、按序的数据流。
-
TCP有三个与发送和重传有关的重要事件:
- 从上层应用程序接收数据:一旦接收到数据,TCP将数据封装到一个报文中,并交给IP。
- 超时:TCP通过重传引起超时的报文来相应超时时间,并重启定时器。
- 收到ACK:TCP会将收到的ACK与它的SendBase(最早未被确认的字节序号)进行比较,并作出相应的动作。
-
TCP每次重传都会将下一次的超时间隔TimeoutInterval设置为之前的两倍,而不是之前有均值和偏差所求的公式.
-
TCP使用冗余ACK(duplicate ACK)就是再次确认某个报文段的ACK,而发送方先前已经收到对该报文段的确认,但是后续的数据可能丢失,因此要再次发送。
-
TCP的差错恢复机制是回退N步GBN和选择重传SR的混合体。
3.5.5 流量控制
- 由于接收方并不一定马上从TCP缓存读取数据,而接收方如果一直发数据,会造成接收缓存溢出。
- TCP为它的应用程序提供了流量控制服务(flow-control service)以消除缓存溢出的可能性。
- TCP通过让发送方维护一个称为接收窗口(congestion control)的变量来提供流量控制,指明接收方还有多少可用的缓存空间。由于TCP是全双工通信的,连接双方的都各自维护一个接收窗口。
- 当接收窗口值为0时,发送方仍会发送一个只有一字节的报文段,最终会被接收方确认,最终缓存将开始清空,并且返回一个非0的接收窗口值。
3.5.6 三次握手,四次挥手-TCP连接管理
- 第一步:客户端的TCP首先向服务器端的TCP发送一个特殊的TCP报文段,该报文段不包含应用层的数据,在首部中的标志位SYN置为1,并随机的选择一个初始序号(client_isn)作为报文段中的序号字段。
- 第二步:该报文段到达服务器端,服务器为该TCP连接分配TCP缓存和变量,并向客户TCP发送允许连接的报文段。在该报文段中,SYN置为1,确认号字段被置为client_isn+1,服务器选择自己的初始序列号server_isn作为序号字段。
- 第三步:客户端收到SYNACK报文段后,客户端也要为该连接分配缓存和变量,可以开始发送数据,SYN置为0,确认号字段为server_isn+1,序号字段为client_isn+1。
-
四次挥手使用FIN字段,如下所示:

3.6 拥塞控制原理
3.6.1 拥塞原因与代价
- 排队时延
- 丢包重传
- 未丢包重传(冗余分组)
- …
3.6.2 拥塞控制方法
- 端到端拥塞控制 :即使网络中存在拥塞,端系统也必须通过对网络行为的观察(如分组丢失与时延)来推断网络是否存在拥塞。网络层没有为运输层拥塞控制提供显示支持。
- 网络辅助的拥塞控制:网络层构件(即路由器)向发送方提供关于网络中拥塞状态的显示反馈信息。这种反馈可以简单的用一个比特来表示。
- 网络辅助的拥塞控制又分为两种
- 1.由网络路由器发给发送方。
- 2.路由器标记或更新从发送方流向接收方的分组中的某个字段来指示拥塞的产生。

3.7 TCP拥塞控制
-
TCP使用端到端拥塞控制。
-
【问题1】 一个TCP发送方如何限制它向其连接发送流量的速率。
- 通过调节拥塞窗口cwnd的值。(cwnd是拥塞窗口(congestion window)是接收方TCP缓存剩余的空间,rwnd是滑动窗口,是发送方发送数据用于回退N步和选择重传的那个窗口。)
-
【问题2】 一个TCP发送方如何感知网络中存在拥塞呢。
- 将 “丢包事件“ 定义为要么出现超时,要么收到三个冗余的ACK。
- 出现丢包事件,发送方就认为路径上出现了拥塞的指示。
-
【问题3】 当发送方感知到端到端的拥塞时,用何种算法改变其发送速率呢?
- TCP拥塞控制算法(TCP congestion control algorithm)
- TCP拥塞控制算法包括以下三个部分。其中慢启动和拥塞避免的差异在增加cwnd的长度上。快速回复是推荐部分。并维护一个阈值threshold,当窗口小于阈值时使用慢启动,大于阈值时使用拥塞避免。
- (1)慢启动
在慢启动(slow-start) 状态中,cwnd的值以1个MSS(最大报文长度)开始并且每当传输的报文段首次被确认就增加1个MSS。(其实等于2的指示倍增,因为上次新增的MSS,下一次确认会带来两个MSS的增加)。直到遇到拥塞,cwnd可以从1开始,也可以变为遇到拥塞时的一半。 - (2)拥塞避免
一旦进入拥塞避免状态,cwnd的值大于是上次遇到拥塞时的值的一半。方法是无论何时到达一个新的确认,就将cwnd增加一个MSS/cwnd字节。 - (3)快速恢复
- 对于收到冗余的ACK,cwnd增加一个MSS。
- 当对丢失报文段的三个个ACK到达时,TCP降低cwnd后进入拥塞避免(阈值和cwnd降为一半)。
- 当出现超时时,进行如同拥塞避免和慢启动的动作后进入慢启动状态。(阈值降低为拥塞时的一半,窗口大小从1个MSS开始)
-
对TCP吞吐量的宏观描述
一
条
连
接
的
平
均
吞
吐
量
=
0.75
×
W
R
T
T
一条连接的平均吞吐量 = \frac{0.75\times W}{RTT}
一条连接的平均吞吐量=RTT0.75×W
其中
W
W
W为出现丢包时拥塞窗口的大小。
- 经高带宽路径的TCP包含丢包率的公式:
一 条 连 接 的 平 均 吞 吐 量 = 1.22 × M S S R T T L 一条连接的平均吞吐量 = \frac{1.22\times MSS}{RTT\sqrt{L}} 一条连接的平均吞吐量=RTTL1.22×MSS