计算机网络: 传输层协议
传输层协议
可靠数据传输的组成
处理比特差错:比特差错指,分组能运输到主机,但具有比特位丢失或错误;又分为非响应分组错误和响应分组错误
- 通过重传分组解决,又因为重传会导致分组冗余,故需要给分组添加编号
- 完备的解决方案: 发送方:发送分组后进入阻塞态,若收到有错误的响应报文,则重传;否则完成委托,等待下一个来自应用层的调用 接收方:有比特差错或无比特差错但序号错,则响应上一个序号的报文,并丢弃当前收到的报文;否则响应当前序号的报文,并增加确认序号
处理丢包:通过超时重传解决,超时即一段时间内未收到正确的响应报文,若超时则响应上一个序号的报文;在此处,发送方接收到有错响应报文时,不立刻重传,而是超时再重传 丢包大概率因为中间路由缓存满而丢弃分组,小概率因为链路中断
上述是一次只传输一个分组的情况,称为停等协议(发送方在收到响应前进入阻塞);为了效率,需要实现流水线传输,有以下方案:
回退
N步(GBN)协议:只要一切正常,效率就可以大幅提高 发送方:维护基序号b,发送方可以一次性发送序号为[b,b+N]内的分组,直到收到ACK_b,才将b右移,并将新的窗口中未发送的分组发送;否则,一旦超时,就将窗口内的分组全部重传 接收方:接收窗口长度只为1,即接收方只接收序号为b的分组,响应策略和停等协议一致(分组出错时响应ACK_b-1) 即,GBN协议是发送方可以发送多个分组的停等协议,当N=1时退化为停等协议,其始终等待b号响应报文的策略使其具有自然有序、且每一时刻序号小于b的报文均已可靠传输的性质选择重传(
SR)协议:上述接收方的策略可以优化,接收方可以选择缓存并自行排序而非丢弃序号错误的分组,相当于将接收方窗口长度拉长,使接收方可以确认所有正确的报文(无论其序号是多少) 对于发送方的好处是,发送方下次超时重传时就不需要重传已经确认的分组,而不是像GBN那样全部重传,发送方的具体策略为:- 一开始全部发送后,对每个分组都设置定时器,一次超时事件只会重传一个分组(“选择重传”的来历)
- 接收到的
ACK确认号不是b(一定会落在窗口内),则进行标记 - 接收到的
ACK确认号是b,则移动b到下一个没被标记的分组,发送新窗口的未被标记分组
接收方的具体策略为:
- 收到序号不为
b的报文:缓存,响应ACK_b - 收到序号为
b的报文:立刻交付它以及窗口内所有已缓存的报文,移动窗口到下一个没有收到过的序号
基于序号有限的现实问题,发送方窗口=接收方窗口≤序号数量的一半,因为响应报文完整/丢失可能导致同步问题:如果接收方窗口长度超过序号数量的一半,那么在一次完美的传输后,接收方窗口会第二次使用相同的序号,此时若响应报文完整,则发送方会第二次使用相同的序号,此次分组实际是新分组;若响应报文丢失,则发送方会重传,此次分组实际是已确认分组,但接收方会误以为是新分组(因为序号相同) 长度不超过序号数量的一半就不会有这样的问题
TCP性质及功能
- 全双工协议,即双方都可作为发送方或接收方
- 面向连接的协议,即双方真正传输数据前需要建立连接、后需要关闭连接
- 支持百分百的可靠数据传输,同时有一定的拥塞控制、流量控制、检错功能
- 通过端口号来标识进程,为了支持全双工,双方都需要提供
IP和端口号 - 协商
MSS(MSS=MTU+IP头部长+TCP头部长,即MSS本身不包含TCP头部),以避免IP分组- 主机是边缘设备,在传输层控制一个
TCP分组的长度可以避免在发送方被网络层分组,有效降低网络负载(因为网络层分组/重组并保证完整传输相比不分组,需要更多开销) - 现代路径发现
MSS:为了防止在中途路由被分组,现代设备可以动态发现整个路径所有网段中的最小MTU而不仅仅是本地网段的MTU,进一步避免被网络层分组
- 主机是边缘设备,在传输层控制一个
TCP协议报文
- 第一行字段:源端口号、目的端口号
- 每个端口号共
16位,端口号分为周知端口号(0~1023)和非周知端口号(1024~65535) - 周知端口号是给服务器使用的,这样客户端就可以默认向使用该端口号作为目的端口号
- 常见的周知端口号:
HTTP~80、FTP传输数据~20、FTP传输控制信息~21、Telnet~23、DNS~53
- 每个端口号共
- 第二行字段:
32位序号,表示本报文所承载数据段的首字节编号 - 第三行字段:
32位确认号,表示本报文所希望的下一个数据段的首字节编号 小于确认号的序号的报文均已被接收方完整接收 - 第四行字段:
4位首部长度:标记首部的字节数,单位为4个字节- 标记位:
URG、ACK、PSH、RST、SYN、FIN 16位接收窗口:用于流量控制,流量控制用于解决发送方发送速率和接收方接收速率不匹配问题 触发流量控制的事件不是超时,超时是触发拥塞控制的事件,而流量控制依赖于响应报文的接收窗口,当接收窗口为0时,表示接收方已经无法再接收,发送方随即停止发送,并试探性地发送一个没有数据的报文直到响应报文的接收窗口不为0
TCP连接过程
- 假设发送方为
A、接收方为B,发送方、接收方期望发送的第一个字节编号分别为a、b那么三次握手过程为:- 发送方发送报文,其中
ACK=0、SYN=1、序列号=a-1 - 接收方发送报文,其中
ACK=1、SYN=1、序列号=b-1、确认号=a - 发送方发送报文,其中
ACK=1、SYN=0、序列号=a、确认号=b这里因为接收方不再发送响应报文,所以发送方下次发送的报文序号仍为a
- 发送方发送报文,其中
- 四次挥手过程为:
- 主动结束方发送报文,其中
FIN=1、ACK=1、序列号=x(上次接收的确认号)、确认号=y(上次接收的序列号+字节数)此后主动结束方不会再发送数据报文,但仍能接收数据报文 - 被动结束方发送响应报文,其中
FIN=0、ACK=1、序列号=y、确认号=x+1 - 被动结束方发送结束报文,其中
FIN=1、ACK=1、序列号=z(被动结束方上次接收报文的确认号)、确认号=x+1 - 主动结束方发送响应报文,其中
FIN=0、ACK=1、序列号=x+1、确认号=z+1防止响应报文丢失,主动结束方最后会进入TIME_WAIT,如果响应报文丢失,被动结束方会超时重传,主动结束方则在TIME_WAIT内受理该重传的FIN报文 注意,这个TIME_WAIT和超时重传是两回事
- 主动结束方发送报文,其中
TCP的附加功能
流量控制:不再赘述
基于序号和确认号在同一份报文内的机制,通常不单独发送响应报文,而是在要发送的数据中捎带上确认信息
期望
RTT(往返时间):通过对最近RTT采样,并加权重(越近的样本权重越大)计算期望RTT方差RTT:测量期望RTT的变化 重传计时器的时间通常设为:期望RTT+4方差RTT在超时事件未发生时,TCP通过它来指导计时器的时间快速重传:每次丢包都等超时后再重传效率过低,因为丢包后,有概率能接收到冗余
ACK报文(确认号相同的报文),发送方可以将这个事件视为丢包的暗示,进行快速重传拥塞起因:发送方的发送速率和中间路由转发速率不匹配导致数据分组冗余 拥塞控制:当丢包事件(超时或接收到若干个冗余
ACK报文,被认为是丢包)发生时,触发拥塞控制机制,其中超时事件相比冗余ACK事件,更能说明链路拥塞(因为冗余ACK起码能接收到,丢包可能是因为物理链路出问题)TCP通过慢启动来控制发送速率:- 慢启动状态:初始发送窗口为一个
MSS,但以指数增长 超时事件发生时,重新进入慢启动状态,将触发超时时候的发送窗口大小的一半设置为慢启动阈值 冗余ACK事件发生时,执行快速重传,进入快速恢复状态 指数增长到慢启动阈值(从未发生过超时时,为无穷大)时,进入拥塞避免状态 - 拥塞避免状态:谨慎地增加发送窗口长度,可能是线性地增加
超时事件发生时,进入慢启动状态,并更新慢启动阈值
冗余
ACK事件发生时,需要作出反应但不应过于剧烈,因此将发送窗口减半而非重置(通常因为有k个冗余ACK,说明中间链路起码还有转发k个分组的能力,所以还要在减半后加上k个MSS),并进入快速恢复状态 - 快速恢复状态:快速重传后,仍可能收到冗余
ACK,每接收一个冗余ACK,相应地增加一个MSS超时事件发生时,同上 当接收到新的ACK而不是冗余ACK时,将发送窗口置为慢启动阈值,进入拥塞避免状态
因此,进入慢启动状态一定是因为超时发生,且初始为
1个MSS进入拥塞避免状态是因为在慢启动时超过了慢启动阈值、或在快速恢复时收到新ACK,初始为慢启动阈值 进入快速恢复状态一定是因为收到冗余ACK,处于快速恢复状态的时间较短- 慢启动状态:初始发送窗口为一个