本博客是通过学习中国科大郑烇老师的计算机网络课程所写的笔记
网络层实现主机之间的逻辑通信,而传输层实现不同主机的进程之间的逻辑通信
传输层不提供保证时延、保证带宽的服务
一、多路复用与多路分解
将主机之间的交付扩展到不同主机的进程间的交付,称为运输层的多路复用和多路分解
- 多路复用:在源主机上,从不同套接字中手机数据块,并为每个数据块封装上首部信息生成报文段,再将该报文段传递到网络层
- 多路分解:将运输层报文端中的数据交付到正确的套接字
1.1、UDP的多路复用与多路分解
UBP的套接字是二元组,即记录着目标IP、目标端口。
若多个UDP报文段有不同的源IP和/或源端口,但具有相同的目的IP和目的端口,那么这些报文段均通过目的套接字被定向到相同的目的进程
1.2、TCP的多路复用与多路分解
TCP的套接字是四元组,即记录着源IP、源端口、目的IP、目的端口
当某个TCP报文到达接收方主机时,四个字段均被用来定向相应的套接字,从而定向到目的进程
二、UDP
UDP是无连接的、不可靠的运输层协议
UDP只提供进程到进程的数据交付和差错检查两种服务,并不能保证所有报文段都能到达目的主机
为什么需要UDP:
- 不需要建立连接
- 分组首部开销小
- 无拥塞控制和流量控制(对于实时流媒体非常有利)
UDP报文段的首部仅包括源端口号、目标端口号、长度和校验和四部分,每部分占2字节
校验和:
- 发送方的UDP对报文段中的所有16比特字的和进行反码运算,求和时遇到任何溢出均会被回卷,得到的结果放入UDP报文段的校验和字段。
- 在接收方,将全部的16比特字(包括校验和)相加,如果结果不为0xFF,说明出现差错
- tips:结果为0xFF,不一定代表无差错,但此时有差错的概率极低,所以被认为无差错
三、TCP
3.1、可靠数据传输协议(rdt)
- 经完全可到的信道的可靠数据传输 rdt1.0
此时,不会出现比特出错和分组丢失
发送方只需要从上层应用得到报文段,产生包含该数据的分组,并将分组发送到信道中
接收方从底层信道接收一个分组,从分组取出数据后,交给上层应用
- 经具有比特出错的信道 rdt2.0
此时,需要提供差错检验(校验和)来判断报文是否出错
接收方需要将报文情况反馈给发送方(ACK/NAK)
发送方需要在收到接收方发来的NAK时,对上一分组进行重传(因此需要缓存已发送未确认的分组)
- 当ACK/NAK出错时 rdt2.1
ACK/NAK也可能出错,如果出错,那么发送方会直接重传旧的分组
此时,接收方需要判断该分组是否已经接收过,需要将已接受的分组丢弃。故而,需要引进序号,来帮助接收方判断新旧分组。
由于此时采用“停止等待”模式,即当发送方收到上一分组的确认时,才会再次发送分组,故而只需要1比特空间来表示序列号
- 使用ACK代替NAK rdt2.2
接收方对最后正确的接收分组发送ACK,因此,当新分组不通过校验时,接收方会发送旧分组的ACK。发送方收到该ACK之后,会重传新分组
可以将接收方发送的ACK理解为,当前已经正确收到的分组,下次请从ACK+1开始发送
- 经具有比特出错、丢包的信道 rdt3.0
此时,发送方发送的分组可能丢包,而接收方发送的ACK也可能出现丢包,无论是哪种情况,接收方均需要检测和恢复丢包
如何检测丢包呢?设置一个时间值,从发送分组后开始计时,超过该时间值时,则认为发生了丢包,对该分组进行重传,即为超时重传机制
故而,需要倒计数定时器,当发送分组后,启动定时器,定时器变为0时,进行重传并重置定时器
然而,上述是基于“停等”转发,所以信道的利用率不高,接下来介绍流水线可靠数据传输
3.2、流水线可靠数据传输协议
引入流水线,就需要解决两个问题
- 增加序号范围,因为可能有许多在传送的未确认报文
- 发送方和接收方需要缓存分组(甚至是多个分组)
所需要的序号范围和缓存空间,取决于采用的是回退N步还是选择重传
3.2.1、回退N步(GBN)
GBN允许发送多个分组而不需要等待确认,但是流水线中的已发送未确认分组不能超过最大允许数N。
base为最早未确认分组的序号;nextseqnum为最小未使用的序号。因此[base, nextseqnum - 1]对应已发送但未被确认的分组,[nextseqnum, base + N - 1]对应要被立即发送的分组(可用分组)
如果分组序号字段比特数为k,那么序号范围为[0, ],所有涉及序号的运算均要模
运算。
GBN相应的三种事件:
- 上层调用:当发送方上层向传输层发送数据时,需要检查窗口是否已满
- 收到ACK:GBN采用累计确认,当ACK=n时,说明正确收到序号n及其以前的所有分组
- 超时重传:GBN协议中,只有一个定时器,所以当出现超时时,将重传所有发送但未确认的分组,并重新启动定时器。若没有已发送未确认分组,停止该定时器
GBN协议中,接收方丢弃所有失序分组。例如,发送方发送了1、2、…、10等10个分组,当分组5丢失(假设已经正确接收1、2、3、4分组)时,即使6、…、10分组到达接收方,也会被接收方丢弃,并且发送ACK=4
3.2.2、选择重传(SR)
对于GBN而言,单个分组的差错,将会导致大量分组的重传,然而这些分组是没有必要重传的
SR接收方将确认一个正确接收的分组,无论其是否按序(例如,没有接收分组3,但是分组4到来,可以正确接收分组4)
SR中,接收方会先缓存失序的分组,等到接收到失序分组前的所有分组后,一并交付给上层。
SR中,接收方发送的ACK表明期待的最小序号的分组。
两个问题:
发送方窗口何时移动?
接收方窗口何时移动?
3.3、面向连接的运输:TCP
最大报文段长度(MMS):TCP可以从发送方缓存中取出并放入报文中的最大数据量
最大传输单元(MTU):本地发送主机发送的最大链路层帧长度(一般为1500)
3.3.1、TCP报文段首部结构
- 序号:标识发送方数据流的字节位置,表示当前报文段第一个字节的编号
- 确认号:表示接收方期望收到的下一个字节的序号,确认已成功接收该序号之前的所有数据
- 首部长度:4比特,该字段指示以32比特为单位的TCP首部长度
- 接收窗口:16比特,用于流量控制,表示接收方可以接收的字节数量
- 标志位:ACK指示确认字段中的值是有效的,RST、SYN、FIN用于TCP连接的建立和拆除
3.3.2、往返事件的估计与超时
3.3.3、可靠数据传输
三个事件:从上层应用程序接收数据、定时器超时、收到ACK
- 超时间隔变化:
- 定时器超时:超时间隔变为原本的两倍
- 收到上层应用数据、收到ACK:由EstimatedRTT和DevRTT确定
- 快速重传:
利用冗余ACK,当收到三个冗余ACK时,不用等到超时再重发,直接进行重发
TCP是累积确认的,只需要使用一个超时定时器。但是,TCP可以正确接收失序的报文并将其缓冲起来,并发送下一个期待的字节序号(没有到达接收方的最小字节序号)。当发送方向接收方发送1、2、3报文时,如果2报文丢失,接收方接收到1、3报文,并且发送方收到来自两者的确认报文,则只会重发2,而不是2、3
- 流量控制:
流量控制:
- TCP让发送方维护一个发送窗口,该窗口指示该接收方还有多少可用的缓存空间。接收方有接收缓存,大小为RcvBuffer。
- 接收方维护两个变量:LastByteRead和LastByteRcvd,分别表示接收方进程读取的最后一个字节的编号、接收方缓存的最后一个字节的编号。那么空闲空间为rwnd=LastByteRcvd - LastByteRead
- 发送方维护两个变量:LastByteSent和LastByteAcked,分别表示最后一个已发送的字节的编号、最后一个已确认的字节的编号,那么LastByteSent - LastByteAcked表示已发送未确认的数据量
- 要保证接收方的缓冲区不溢出,就需要保证:LastByteSent - LastByteAcked <= rwnd
3.3.4、TCP连接建立与拆除
TCP连接管理
TCP连接建立(三次握手):
- 客户端向服务端发送请求建立报文(SYN=1,客户端随机选择一个起始序号)
- 服务端向客户端发送允许连接报文(SYN=1,服务端随机选择一个起始序号,并为该连接分配缓存和变量)
- 客户端向服务端发送确认报文(SYN=0,客户端为该连接分配缓存和变量)
TCP连接关闭(四次握手):
- 客户端发送FIN报文
- 服务器发送ACK报文(此时,客户端能收来自服务端的分组,但不能向服务器发送分组)
- 服务器发送FIN报文
- 客户端发送ACK报文
3.3.5、拥塞控制
拥塞控制方法:端到端、网络辅助
- 端到端:端系统通过对网络行为的观察实现拥塞控制
- 网路辅助:路由器显示通过发送方其在输出链路上支持的最大主机发送速率(直接反馈、通过接收方反馈)
TCP采用端到端的拥塞控制方式
- 慢启动:
cwnd的值以1MSS开始并且每当传输的报文段首次被确认时,拥塞窗口cwnd就增加1MSS,呈线性增长
何时结束慢启动呢?
- 超时:cwnd为某个值时,发生了超时,TCP发送方会将ssthresh(慢启动阈值)设置为cwnd/2,并将cwnd置为1,重新开始慢启动
- 达到阈值ssthresh:结束慢启动,进入拥塞避免阶段(线性增)
- 三次冗余ACK:TCP执行快速重传,ssthresh置为cwnd/2,并将cwnd减半再加上3个MSS,然后进入快速恢复阶段
- 拥塞避免:
进入此阶段,说明此时的cwnd的值大约是上次遇到拥塞时的值的一般。
每个RTT只将cwnd的值增加1MSS
何时结束拥塞避免呢?
- 超时:ssthresh置为cwnd/2,cwnd被置为1,开始慢启动
- 三次冗余ACK:TCP执行快速重传,ssthresh置为cwnd/2,并将cwnd减半再加上3个MSS,然后进入快速恢复阶段
- 快速恢复:
将ssthresh设置为当前cwnd的一半。将cwnd设置为 ssthresh + 3个MSS
每收到一个冗余ACK,cwnd的值就增加1MSS
何时结束快速恢复?
超时:ssthresh置为cwnd/2,cwnd被置为1,开始慢启动
报文到达:当丢失报文段的第一个 ACK 到达时,TCP 在将cwnd降为ssthresh后,进入拥塞避免状态。
如果没有理解上述表述的话,可以好好看看下面这张图!表述的不能再详细了