运输层
概述运输层服务
运输层为运行在不同主机上的应用进程提供直接的通信服务。
运输层协议是在端系统中而不是在路由器中实现的。具体实现过程如下:
发送端:运输层将从发送应用程序进程接收到的报文转换成运输层分组,即运输层报文段(先将应用报文划分成小块,再加上运输层首部)。运输层将这些报文段发送给网络层,网络层将其封装成网络分组(即数据报)并向目的地发送。网络路由器只作用于数据报的网络层字段,而不检查封装在该数据报运输层报文段的字段。
接收端:网络层从数据报中提取运输层报文段并将该报文段向上交给运输层。
运输层和网络层的关系
网络层提供主机间的逻辑通信,运输层为运行在不同主机上的进程之间提供逻辑通信。
在端系统中运输层协议将来自应用进程的报文移动到网络边缘(即网络层)。
计算机网络中可以安排多种运输层协议,每种协议为应用程序提供不同的服务模型。
运输层协议能够提供的服务尝尝受制于底层网络层协议的服务模型。
即使网络层不能保证运输层报文段的机密性,运输协议也能使用加密来确保应用程序报文不被入侵者读取。
运输层概述
UDP(用户数据报协议):提供不可靠、无连接的服务,只能提供数据交付和差错检查。
TCP(传输控制协议):提供可靠的、面向连接的服务。
多路复用与多路分解
一个进程有一个或多个套接字(ip+端口号),接收主机怎样将一个到达的运输层报文段定向到适当的套接字?
多路分解:在接收端,运输层检查这些字段,标识出接收套接字,进而将报文段定向到该套接字。将运输层报文段中的数据交付到正确的套接字的工作称为多路分解。
多路复用:在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息从而生成报文段,然后将报文段传递到网络层,这所有的工作称为多路复用。
运输层报文段的结构:
应用程序的客户端让运输层自动地分配端口号,服务器端则分配一个特定的端口号。
UDP套接字由一个二元组全面标识,该二元组包含一个目的ip和一个目的端口号。
TCP套接字由一个四元组全面标识,该四元组包含源ip地址、源端口号、目的ip地址、目的端口号。
UDP和TCP对比
无连接运输:UDP
UDP优点:
- 关于发送什么数据以及何时发送的应用层控制更为精细(没有拥塞控制机制),按需随时发送。
- 无需建立连接,不会引入建立连接的时延。
- 无连接状态,TCP维护连接状态需要维护包括接收和发送缓存、拥塞控制参数、序号与确认号的参数,而UDP不需要,因此当应用程序运行在UDP上,某些专门用于某种特定应用的服务器一般都能支持更多的活跃用户。
- 首部开销小。UDP:8Byte,TCP:20Byte
但是因为UDP没有拥塞控制,所以如果网络进入拥塞状态,UDP的高丢包率会引起TCP的发送方大大减小它们的速率。
采用UDP的应用:
- 远程文件服务器(NFS)
- 流式多媒体
- 因特网电话
- 网络管理(SNMP)
- 选路协议(RIP)
- 域名解析(NDS)
UDP报文段:
UDP首部有4个字段,每个字段由两个字节组成。
长度:首部+数据。
接收方通过检验和检查该报文段是否出现问题。
UDP检验和:
- 将报文段切成16bit的数据
- 对报文段中所有16比特字的和进行反码运算,求和时任何溢出都被回卷(进的位回到个位)
- 因为原码+反码=全1,所以检查是否为全1即可
可靠数据传输原理
rdt1.0~rdt3.0都使用停等协议
停等协议:发送方发送数据后等待接收方的响应
经完全可靠的信道的可靠信息传输:rdt1.0
底层信道完全可靠。
有限状态机(FSM)
因为底层信道完全可靠,所以接收方不需要反馈信息给发送方。
经具有比特差错信道的可靠数据传输:rdt2.x
2.x 解决了流控问题
底层信道分组中的比特可能受损。
2.0 发送的数据受损
采用自动重传请求协议(ARQ),进行差错检测、接收方反馈(ACK/NAK)、重传
重传:使用缓冲区缓存已发出但未收到反馈的报文段
2.1 ACK/NAK受损
发送方不知道接收方的情况,只能重传。
但是可能导致接收方的重复接收,那么接收方怎么知道收到的分组是新的还是一次重传?于是引入分组编号。
因为只有两种状态:新的分组或者重传,所以只需要编号0和1。如果收到的分组和上一次收到的分组编号一致,说明是一次重传
2.2 使用一个无NAK的可靠数据传输协议
重复的ACK = NAK:不发送NAK,而是对上次正确接收的分组发送一个ACK;即当发送方接收到冗余的ACK,就知道接收方没有正确接收到跟在被确认两次的分组后的分组。
经具有比特差错的丢包信道的可靠数据传输:rdt3.0
除了比特受损外,底层信道还会丢包。
设置倒计数定时器,面对超时的数据进行重传。如果数据本身未丢失只是超时了,就会导致冗余数据分组,直接忽略即可。
流水线可靠数据传输协议
因为rdt3.0使用的是停等协议,所以效率较低,于是使用流水线技术。
允许发送方发送多个分组并无需等待确认
- 原本的两个序号(0,1)不够用,必须增大序号范围
- 发送方最低限度应能缓存那些已发送但未被确认的分组
- 接收方需缓存那些已经正确接收的分组
当流水线技术中丢失一个分组,差错恢复有两种方法:回退N步和选择重传。
回退N步协议(GBN)
累计确认ACK(n):接收方对序号n之前包括n在内的所有分组进行确认
超时事件:发送方重传所有已发送但未被确认的分组,发送方只使用一个定时器,如果收到一个ACK但是仍有已发送但未被确认的分组,则定时器被重新启动。
分组失序:接收方无缓存,所以直接丢弃,重发按序到达的最高序号后面的分组
滑动窗口大小:\(\color{red}{发送端\leq 2^{k}-1,接收端=1}\)
选择重传(SR)
发送方:
- 从上层收到数据:如果下一个可用于该分组的序号在窗口内,则将数据打包并发送。
- 超时(n):为每个分组定义定时器;重传分组n,重置定时器
- 收到确认(n)在\([sendbase,sendbase+N-1]\)范围内:标记分组n为已接收,如果n是发送方窗口基序号sendbase,则将窗口基序号推到下一个未确认序号
接收方:
- 分组序号n在\([rcvbase,rcvbase+N-1]\)范围内
- 发送n的确认ACK(n)
- 如果分组序号失序,将其缓存
- 按序分组:将该分组以及以前的缓存的序号连续的分组一起交付给上层,将窗口前推到下一个未收到的分组。
- 再次发送n的确认ACK
- 其他情况,忽略该分组
接收方窗口\(\leq 2^{k-1}\),即窗口的长度必须小于等于序号空间大小的一半
面向连接的运输:TCP
TCP的特点
面向连接:必须相互发送某些预备报文段,以建立确保数据传输的参数。
全双工服务:可双向同时传输数据。
点对点连接:仅能存在于两个端系统之间。
三次握手:客户端先发送一个特殊的TCP报文段,服务器用一个特殊的报文段进行响应,这两个报文段都不含应用层数据;最后客户端用第三个特殊报文段作为响应,第三个报文段可以承载有效数据。
可靠的字节流:TCP可以从缓存中取出并放入报文段中的数据数量受限于最大报文段长度MSS,MSS由本地发送主机发送的最大链路层帧长度【即最大运输单元MTU】设置。MSS要保证加上TCP/IP首部长度(通常是40字节)将适合单个链路层帧。
注意:MSS是指报文段中应用层数据的最大长度,而不是指包括首部的TCP报文段的最大长度。
TCP报文段结构
源端口和目的端口:各占2字节,端口是应用层和运输层的服务端口。运输层的复用和分解都需要通过端口实现。
序号:占4字节,TCP连接中传输的数据流的每一个字节都有一个序号,序号字段的值指的是本报文段所发送的数据的第一个字节在整个报文字节流中的序号。
确认号:占4字节,是期望收到对方的下一个报文段的数据段的第一个字节的序号。
首部长度:占4bit,该字段指示了以32bit的字为单位的TCP首部长度。(通常选项字段为空,TCP首部典型长度是20字节)
保留字段:占6bit,保留为今后使用,但目前应置为0。
URG:紧急比特,UGR=1表明此报文段中有紧急数据,应尽快送达。
ACK:确认ACK,只有当ACK=1时确认号字段才有效;ACK=0时,确认号无效。
PSH:接收到PSH=1的报文段,就尽快交付给接收应用进程,而不再等到整个缓存都填满再向上交付。
RST:当RST=1时,表名TCP连接中出现严重差错,必须释放连接,然后再重新建立运输链接。
SYN:同步比特,SYN=1,这是一个连接请求或连接接收的报文。
FIN:释放一个链接,当FIN=1,此报文段的发送端的数据已经发送完毕,并要求释放运输链接。
窗口:占2字节,窗口字段用来控制对方发送的数据量,单位为字节。
检验和:占2字节,检验范围包括首部和数据两部分,计算时要在TCP报文段的前面加上12字节的伪首部。
紧急指针:占2字节,指出本报文段中紧急数据的最后一个字节的序号。
填充:为了使整个首部的长度是4字节的整数倍。
估计往返时间RTT
在任意时刻,仅为一个已发送但目前尚未被确定的报文段估计SampleRTT,从而产生一个接近每个RTT的新的SampleRTT。
TCP不为已被重传的报文段计算SampleRTT。
因为RTT有波动,所以利用加权平均值计算EstimatedRTT
\[EstimatedRTT=0.875*EstimatedRTT+0.125*SampleRTT\]
估算SampleRTT偏离EstimatedRTT的程度:
\[DevRTT=(1-\beta)\cdot DevRTT+\beta\cdot|SampleRTT-EstimatedRTT|,\beta推荐值为0.25\]
第一次计算时\(DevRTT=0.5*SampleRTT\)
TCP中确定重传超时间隔的方法:
\[TimeoutInterval=EstimatedRTT+4\cdot DevRTT\]
推荐初始的\(TimeoutInterval = 1s\)
出现超时 \(RTO*2\)
可靠数据传输
TCP使用单一定时器。
从上面应用程序收到数据e:如果当前定时器没有运行,启动定时器并向IP传递报文段。
定时器超时:重传具有最小序号但仍未应答的报文段并启动定时器。
收到ACK,具有ACK字段值y:如果y > SendBase
,重置Sendbase = y
,如果仍有尚未确认的报文段,启动定时器。
(SendBase是最早未被确认的字节的序号,SendBase - 1是指接收方已正确按序接收到的数据的最后一个字节的序号)
超时间隔加倍:每次超时时间发生,TCP重传时都会将下一次的超时时间间隔设为先前的两倍。
快速重传:当TCP接收方检测到了数据流中的一个间隔,就会不断重发它期望的这个ACK,当冗余ACK的数量达到3的时候,就采用快速重传机制,在超时之前就重传该分组。
流量控制
接收方在反馈时,将缓冲区剩余空间的大小填充在报文段首部的窗口字段中,通知发送方
主机A向主机B发送文件,主机B接收缓存的大小是RcvBuffer;主机B上的应用进程从缓存读出的数据流的最后一个字节的编号是LastByteRead;从网络中到达的并且已放入主机B接收缓存中的数据流的最后一个字节的编号。
接收窗口的大小:\(rwnd = RcvBuffer - (LastByteRead - LastByteRead)\)
为让发送方在接收方的缓存满了之后可以及时了解什么时候又有新的空间,发送方持续向接收方发送只有一字节数据的报文段。
TCP连接管理
3次握手,4次分手
拥塞控制协议
拥塞控制方法:
网络辅助的拥塞控制
直接网络反馈:路由器以阻塞分组的形式通知发送方“网络拥塞了”
经由接收方的网络反馈:路由器标识从发送方流向接收方分组中的某个字段以指示拥塞的产生,由接收方通知发送方“网络拥塞了”(至少要经过一个完整的往返时间)
端到端拥塞控制
网络层不为拥塞控制提供任何帮助和支持
端系统通过对网络行为(丢包或时延增加)的观测判断网络是否发生拥塞
目前TCP采用该种方法(通过三个冗余的ACK实现)
TCP拥塞控制
Reno算法
加性增,乘性减(AIMD)
出现丢包事件后将当前 CongWin 大小减半,可以大大减少注入到网络中的分组数
当没有丢包事件发生了,每个RTT之后将CongWin增大1个MSS,使拥塞窗口缓慢增大,以防止网络过早出现拥塞
慢启动和拥塞避免
建立连接时,CongWin = 1 MSS
eg:
- MSS(最大报文段大小) = 500字节
- CongWin = 1 MSS = 500字节 = 500 * 8 比特
- RTT = 200毫秒
所以\(初始速率=\frac{500 * 8}{200}=20kbps\)
可用带宽 >> MSS/RTT
初始阶段以指数的速度增加发送速率
连接初始阶段,以指数的速度增加发送速率,直到发生一个丢包事件为止
每收到一次确认则将CongWin的值增加一个MSS
对收到3个重复ACK的反应
将CongWin减为原来的一半
线性增大拥塞窗口
对超时事件的反应
门限值设为当前CongWin的一半(门限值初始值65kB)
将CongWin设为1个 MSS大小;
窗口以指数速度增大
窗口增大到门限值之后,再以线性速度增大
- 当 TCP 连接进行初始化时,将拥塞窗口置为 1。图中的窗口单位不使用字节而使用报文段。慢开始门限的初始值设置为 16 个报文段,即 ssthresh = 16。
- 发送端的发送窗口不能超过拥塞窗口 cwnd 和接收端窗口rwnd 中的最小值。我们假定接收端窗口足够大,因此现在发送窗口的数值等于拥塞窗口的数值。
- 当拥塞窗口 cwnd 增长到慢开始门限值 ssthresh 时(即当 cwnd = 16 时),就改为执行拥塞避免算法,拥塞窗口按线性规律增长。
快速恢复
3个冗余ACK进入快速重传后
每收到一个冗余ACK:CongWin++
直至收到一个新的ACK:CongWin=门限值,重新进入拥塞避免;因为已经收到了三个冗余ACK,所以实际cwnd=门限值+3
在进入快速恢复之后及重新进入拥塞避免之间,如果出现超时现象,直接按照前述超时事件进行处理
总结
TCP吞吐量
假定当丢包事件发生时,窗口大小为 W,此时吞吐量为W/RTT
丢包事件发生后,窗口大小减为W/2, 吞吐量为W/2RTT,因此平均吞吐量为: 0.75 W/RTT
吞吐量是丢包率(L)的函数:\(\frac{1.22\cdot MSS}{RTT\sqrt{L}}\)
并行TCP连接
考虑一段速率为R且支持9个在线客户-服务器应用的链路,每个应用使用一条TCP连接,如果一个新的应用加入进来
- 如果新的应用也使用一条TCP连接,则每个应用得到差不多相同的传输速率\(\frac{R}{10}\)
- 如果新的应用使用了11个并行的TCP连接,那这个应用就会不公平的分到超过\(\frac{R}{2}\)的带宽