计算机网络(运输层)
基本理论和基本机制
- 多路复用/分用
- 可靠数据传输机制
- 流量控制机制
- 拥塞控制机制
Internet的运输层协议
- TCP
- UDP
概述
传输层协议为运行在不同Host上的进程提供了一种逻辑通信机制
端系统运行传输层协议
- 发送方:将应用递交的信息分成一个或多个的Segment,并向下传给网络层
- 接收方:将收到的Segment组装成消息,并向上交给应用层
网络层提供主机之间的逻辑通信机制
传输层提供应用进程之间的逻辑通信机制,位于网络层之上,依赖于网络层服务,对网络层服务进行(可能的)增强
Internet传输层协议
- TCP:可靠、按序的交付服务
- 拥塞控制
- 流量控制
- 连接建立
- UDP:不可靠的交付服务
- 基于“尽力而为”的网络层,没有做可靠性的扩展
- 都不提供延迟、带宽方面的保障
端口
协议端口号(protocol port number), 或通常简称为端口(port) 。这就是说,虽然通信的终点是应用进程,但只要把所传送的报文交到目的主机的某个合适的目的端口,剩下的工作(即最后交付目的进程)就由TCP 或UDP 来完成。(协议端口是软件端口)
运输层收到IP层交上来的运输层报文时,就能够根据其首部中的目的端口号把数据交付应用层的目的应用进程。
TCP/IP 的运输层用一个16 位端口号来标志一个端口。但请注意,端口号只具有本地意义,它只是为了标志本计算机应用层中的各个进程在和运输层交互时的层间接口。在互联网不同计算机中,相同的端口号是没有关联的。16 位的端口号可允许有65535 个不同的端口号,这个数目对一个计算机来说是足够用的。
服务器端使用的端口号
熟知端口号(0~1023)
登记端口号(1024~49151)
这类端口号是为没有熟知端口号的应用程序使用的。使用这类端口号必须在IANA 按照规定的手续登记,以防止重复。
多路复用/分用
分用
主机收到IP数据报,每个数据报携带源IP地址、目的IP地址、一个传输层的段(Segment),每个段携带源端口号和目的端口号。主机收到Segment后,传输层协议提取IP地址和端口号信息,将Segment导向相应的Socket
无连接分用
用目的IP地址和目的端口号标识,主机收到UDP段后,检查段中的目的端口号,将UDP段导向绑定在该端口号的Socket(来自不同源IP地址或源端口号的IP数据包被导向同一个Socket)
面向连接的分用
用源IP地址,源端口号,目的IP地址,目的端口号四元组标识;接收端利用所有的四个值将Segment导向合适的Scoket。服务器可能同时支持多个TCP Socket(每个Socket用自己的四元组标识);Web服务器为每个客户端开不同的Socket
多线程Web服务器(由P4创建多个线程)
UDP
(User Datagram Protocol)
- 基于IP协议,实现了多路复用/分用以及简单的错误校验
- “Best effort” 服务,UDP可能会丢失以及非按序到达
- 无连接,UDP发送方和接收方之间不需要握手,每个UDP段的处理独立于其他段
- 面向报文的,UDP一次交付一个完整的报文。因此,应用程序必
须选择合适大小的报文。若报文太长, UDP 把它交给IP 层后, IP 层在传送时可能要进行分片,这会降低IP 层的效率。反之,若报文太短, UDP 把它交给IP 层后,会使IP 数据报的首部的相对长度太大,这也降低了IP 层的效率。
UDP为什么存在
- 无需建立连接,减少延迟
- 实现简单:无需维护连接状态
- 头部开销少
- 没有拥塞控制:应用可以更好地控制发送时间和速率
用途:
- 常用于流媒体应用
- DNS、SNMP
- 在UDP上实现可靠数据传输(应用层自己实现)
报文格式
检验和:检测UDP段在传输中是否发生错误(如位反转)
在计算检验和时,要在UDP 用户数据报之前增加12 个字节的伪首部。所谓“伪首部”是因为这种伪首部并不是UDP 用户数据报真正的首部。只是在计算检验和时,临时添加在UDP 用户数据报前面,得到一个临时的
UDP 用户数据报。检验和就是按照这个临时的UDP 用户数据报来计算的。伪首部既不向下传送也不向上递交,而仅仅是为了计算检验和。UDP 计算检验和的方法和计算IP 数据报首部检验和的方法相似。但不同的是: IP 数据报的检验和只检验IP 数据报的首部,但UDP 的检验和是把首部和数据部分一起都检验。在发送方,首先是先把全零放入检验和字段。再把伪首部以及UDP 用户数据报看成是由许多16 位的字串接起来的。若UDP 用户数据报的数据部分不是偶数个字节,则要填入一个全零字节(但此字节不发送)。然后按二进制反码计算出这些16 位字的和。将此和的二进制反码写入检验和字段后,就发送这样的UDP 用户数据报。在接收方,把收到的UDP 用户数据报连同伪首部(以及可能的填充全零字节)一起,按二进制反码求这些16 位字的和。当无差错时其结果应为全l 。否则就表明有差错出现,接收方就应丢弃这个UDP 用户数据报(也可以上交给应用层,但附上出现了差错的警告)。图5-7 给出了一个计算UDP 检验和的例子。这里假定用户数据报的长度是15 字节,因此要添加一个全0 的字节。读者可以自己检验一下在接收端是怎样对检验和进行检验的。不难看出,这种简单的差错检验方法的检错能
力并不强,但它的好处是简单,处理起来较快。
可靠数据传输原理
概述
什么是可靠?
- 不错、不丢、不乱
可靠数据传输对应用层、传输层、链路层都很重要,信道的不可靠特性决定了可靠数据传输协议(rdt)的复杂性
从提供服务的视角来看:
从实现的角度来看:
数据单向传输,但控制信息双向流动
ARQ协议
具有以下rdt机制的协议:
- 确认机制(ACK):接收方显式地告知发送方分组已正确接收
- NAK:接收方显式地告知发送方分组有错误
- 发送方收到NAK后,重传分组
停止等待协议
流水线机制与滑动窗口协议
允许发送方在收到$ACK$之前连续发送多个分组
- 需要更大的序列号范围
- 发送方/接收方需要更大的存储空间以缓存分组
为了实现流水线机制,需要滑动窗口协议
窗口
- 允许使用的序列号范围
- 尺寸为N表示最多有N个等待确认的消息
滑动窗口
- 随着协议的运行,窗口的序列号空间内向前滑动
绿色:已经发送了且成功确认的
黄色:发送了但还没成功确认的
蓝色:窗口中还可以使用的序列号
$GBN$协议
$(Go—Back—N)$
发送方
$ACK(n)$:确认到序列号n(包含n)的分组均已被正确接收,可能收到重复$ACK$
为发出的分组设置计时器(timer)
- 超时:重传序列号大于等于n,还未收到的$ACK$的所有分组
接收方
- 发送拥有最高序列号的、已被正确接受的分组的$ACK$,可能产生重复的$ACK$,只需要记住唯一的$expecteseqnum$
- 对于乱序到达的分组,直接丢弃(接收方没有缓存)重新确认序列号最大的、按序到达的分组
示例:
$SR$协议
$(Selective Repeat)$
接收方对每个分组单独进行确认,设置缓存机制,缓存乱序到达的分组,发送方只重传那些没收到$ACK$的分组,为每个分组设置定时器
发送方窗口:N个连续的序列号,限制已发送且未确认的分组。
与$GBN$相比,多了接收方窗口,两个窗口不同步
示例:
$SR$协议存在的问题
在$(a)$的情况下,前三个分组的$ACK$丢失,触发超时发送方重传这些分组。因此,接收方下一步接收序号为0的分组,即重发第一个分组的副本
在$(b)$的情况下,对前三个分组都被正确交付。因此发送方向前移动窗口并发送第4、5、6个分组,其序号分别为3、0、1。序号为3的分组丢失,但序号为0的分组到达。
对于接收方而言,两种情况是等同的,没有办法区分是第1个分组的重传还是第5个分组的初次传送,显然当窗口大小比序号空间小1时协议无法工作
事实上序号空间大小与窗口尺寸需满足$N_s + N_R <= 2^k$
TCP
概述
- 点对点:一个发送方,一个接收方
- 可靠、按序的字节流
- 流水线机制:TCP拥塞控制和流量控制机制设置窗口尺寸
- 发送方和接收方都有缓存
- 全双工,同一连接中能够传输双向数据流
- 面向连接
- 流量控制机制
TCP段结构
- $URG$用来指示报文段里存在着被发送端的上层实
体置为"紧急"的数据。紧急数据的最后一个字节由16 比特的紧急数据指针字段( urgent data pointer field) 指出。当紧急数据存在并给出指向紧急数据尾指针的时候, TCP 必须通知接收端的上层实体。(实践中没有使用) - $seqno$:指segment中第一个字节的编号,建立TCP连接时双方随机选择序列号
- $ackno$:希望接受到的下一个字节的序列号,采用累积确认,即该序列号之前的所有字节均已被正确接收
- $win$:接收窗口字段,指示接收方愿意接受的字节的数量
在TCP中处理乱序到达的Segment的方法在TCP规范中没有规定,由TCP实现者自己决策
TCP可靠数据传输
- 流水线机制
- 累积确认
- TCP使用单一重传定时器
- 触发重传的时间
- 超时
- 收到重复$ACK$
$RTT$和超时
设置定时器的超时时间,过短引起不必要的重传,过长对段丢失时间反应慢
测量从段发出去到收到$ACK$的时间$SampleRTT$,测量多个$SampleRTT$求平均值得到估计值$EstimatedRTT$,然后有,通常α=0.125
TCP发送方事件
从应用层收到数据
- 创建segment,序列号是第一个字节的编号,开启计时器,设置超时时间$TimeOutInterval$
超时
- 重传引起超时的segment
- 重启计时器
收到$ACK$
- 如果确认此前未确认的segment,更新$SendBase$,如果窗口中还有未被确认的分组,重新启动计时器
每次TCP 超时重传时都会将下一次的超时间隔设为先前值的两倍例如,假设当定时器第一次过期时,与最早的未被确认的报文段相关联的$Timeou tlnterval $是0. 75 秒。TCP 就会重传该报段,并把新的过期时间设置为I. 5 秒。如果I. 5 秒后定时器又过期了,则TCP 将再次重传该报文段,并把过期时间设置为3.0
秒。因此,超时间隔在每次重传后会呈指数型增长。然而,每当定时器在另两个事件(即收到上层应用的数据和收到$ACK$) 中的任意一个启动时, $Timeoutlnterval$ 由最近的$EstimatedRTI$值与$DevRTT $值推算得到。
TCP $ACK$生成
冗余$ACK (duplicate ACK )$ 就是再次确认某个报文段的$ACK$, 而发送方先前已经收到对该报文段的确认。
快速重传机制
TCP的实现中,如果发生超时,超时时间间隔将重新设置,超时时间间隔将倍,导致其很大,重发丢失的分组之前要等待很长时间。
因为发送方经常一个接一个地发送大量的报文段,如果一个报文段丢失, 就很可能引起许多一个接一个的冗余$ACK $。如果TCP 发送方接收到对相同数据的3 个冗余$ACK$, 它把这当作一种指示,说明跟在这个已被确认过3 次的报文段之后的报文段已经丢失,TCP就执行快速重传,在该报文段的定时器过期之前重传丢失的报文段。
TCP 流量控制
接收方为TCP连接分配buffer,上层应用可能处理buffer中数据的速度较慢,流量控制使发送方不会传输的太多、太快以至于淹没接收方(buffer溢出)
在$RcvWindow=0$时也可以发送segment防止死锁的情况,具体可以参照$CS144 lab3$
TCP 连接管理
三次握手(建立连接)
四次握手(关闭连接)
TCP的有限状态机
拥塞控制原理
概述
拥塞(Congestion):太多发送主机发送了太多数据或者发送速度太快以至于网络无法处理
表现:
- 分组丢失(路由器缓存溢出)
- 分组延迟过大(在路由器缓存中排队)
拥塞的成因和代价
(下面的C在书中使用的是R)
场景1
(C是路由器的带宽)
当分组的到达速率接近链路容量时,分组经历巨大的排队时延。
==思考:为什么会发生这样的现象==
场景2
$λ_{in}$表示应用程序将初始数据发送到套接字中的速率
$λ_{in}^‘$表示运输层向网络中发送报文段(含有初始数据或重传数据)的速率,也称为供给载荷
$(a)$因为假定没有丢失,平均主机发送速率$λ_{in}$不能超过$\frac{R}{2}$,R是链路带宽(路由器带宽)
场景3
在$λ{in}$很小时,路由器缓存的溢出是很少见的,当有更多的初始数据被发送到网络中并交付到目的地时,溢出依然很少,因此对于较小的$λ{in}$增大会导致$λ_{out}$增大
分析$λ{in}$(因此$λ{in}^‘$)很大时的情况。考虑路由器$R2$ 。不管丛的值是多大,到达路由器$R2$ 的A -C 流量(在经过路由器$R1$ 转发后到达路由器$R2$) 的到达速率至多是R, 也就是从$R1$ 到$R2$ 的链路容量。如果从,对于所有连接(包括B-D 连接)来说是极大的值,那么在$R2$ 上, B-D 流量的到达速率可能会比A-C流量的到达速率大得多。因为A-C 流量与B-D 流量在路由器$R2$ 上必须为有限缓存空间而竞争,所以当来自B-D 连接的供给载荷越来越大时, A-C 连接上成功通过$R2$ ( 即由于缓存R/2溢出而未被丢失)的流量会越来越小。在极限情况下,当供给载荷趋近于无穷大时, $R2$ 的空闲缓存会立即被8-D 连接的分组占满,因而A-C ~ 言连接在$R2$ 上的吞吐量趋近于0 。这又一次说明在重载的极限情况下, A-C 端到端吞吐量将趋近于0 。
拥塞控制
端到端拥塞控制:网络层不需要显式的提供支持,端系统通过观察loss,delay等网络行为判断是否发生拥塞,TCP采用这种方法
网络辅助的拥塞控制:路由器向发送方显式地反馈网络拥塞信息,这种反馈可以简单地用一个比特来指示链路中的拥塞情况。
例如、在ATM 可用比特率(Available Bite Rate, $ABR$) 拥塞控制中.路由器显式地通知发送方它(路由器)能在输出链路上支持的最大主机发送速率。
TCP拥塞控制
基本原理
Sender限制发送速率
定义$CongWin$(congestion window)
动态调整以改变发送速率
反映所感知到的网络拥塞
如何感知网络拥塞
- $Loss事件 = timeout 或3个重复ACK$,发生$Loss$事件后,发送方降低速率
如何合理地调整发送速率
- 加性增—乘性减:$AIMD$
- 慢启动:$SS$
$AIMD$
原理:逐渐增加发送速率,谨慎探测可用带宽,直到发生$Loss$
- $Additive \space Increase$:每个$RTT$将$CongWin$增大一个$MSS$(最大的段的长度)—拥塞避免
- $Multiplicative \space Decrease$:发生$Loss$后将$CongWin$减半
慢启动$SS$
TCP连接建立时,设置一个较低的初始速率,可用带宽可能远远高于初始速率,我们希望带宽快速增长。当连接开始时,速率指数性增长
例如连接建立时$CongWin = 1$,$MSS=500byte$,$RTT=200msec$,初始速率=$20kbps$
指数性增长
- 每个$RTT$将$CongWin$翻倍(每个确认到达时翻倍)
- 初始速率很慢,但是快速攀升
$Threshold$变量
- $Loss$事件发生时,被设置为$Loss$事件前$CongWin$值的一半
- 用来实现$CongWin$达到$Loss$事件前值的一半时,由指数增长切换为线性增长(拥塞避免)
3个重复$ACK$:
- $CongWin$切到原来的一半然后线性增长
$Timeoout$事件:
- $CongWin$直接设为1,然后指数增长,达到$Threshold$后再线性增长
3个重复$ACK$表示网络还能传输一些segment
timeout事件表明拥塞更为严重
TCP拥塞控制算法
例题:
TCP的公平性
如果K个$TCP \space Session$共享相同的瓶颈带宽,那么每个Session的平均速率为R/K
最后会收敛到中间的线上
$UDP$
- 多媒体应用通常不使用TCP以免被拥塞控制机制限制速率
- $UDP$以恒定速率发送,能够容忍丢失,产生了不公平
并发TCP连接
某些应用会打开多个并发连接产生不公平
链路速率为R,已有9个连接
- 新应用请求1个TCP,获得R/10的速率
- 新来的应用请求11个TCP,获得一半以上的速率