【计算机网络】运输层
计算机网络:自顶向下方法(第五版&第七版)学习笔记,第三章运输层
本章逻辑:概述-三个原理-UDP和TCP原理
概述
-
运输层为进程提供逻辑通信(logic communication),网络层为主机提供逻辑通信
-
运输层协议在主机中实现,将进程的报文转化曾报文段(segment)
-
网络层仅作用于运输层报文段的网络层字段而不检查,接收时网络层提取运输层报文段转交运输层
-
运输层提供的服务受限于网络层提供的服务(如时延带宽等),但运输层可以提供网络层提供不了的服务(如安全、数据可靠等)
-
网络层协议IP,尽力而为交付(best-effort delivery service)不保证交付,是不可靠服务(unreliable service)
-
运输层协议的基本服务
- 将网络层的传输服务扩展到进程间的传输,这种“扩展”叫多路复用(multiplexing)和多路分解(demultiplexing)
- 差错检查(error checking)
-
差错检查是一个端到端原则(end-end principle):这种功能必须基于端到端实现,在较低级别设置这种功能无价值/冗余
-
TCP还提供:可靠数据传输、拥塞控制
多路复用(multiplexing)和多路分解(demultiplexing)
- 多路分解(demultiplexing):将运输层报文段的数据交付到正确的socket,即检查目的端口号并定向到对应socket
- 多路复用(multiplexing):从socket中收集数据并封装首部信息生成报文段,并传到网络层
- socket有唯一标识符(端口号)
- 报文段有特殊字段指示需要交付到的socket,至少包括源端口号字段(source port number field)、目的端口号字段(destination port number field)
- 分类为无连接(connectionless)(如UDP)、面向连接(connection-oriented)(如TCP),socket的标识分别为二元组(目的IP、目的端口号)、四元组(源IP,源port,目的IP,目的port)
可靠数据传输(Reliable Data Transfer)
- 可靠数据传输协议(Reliable Data Transfer Protocol)
- 用有限状态自动机FSM(finite state machines)说明发送方/接收方
- (???)ARQ(Automatic Repeat Request,自动重传请求协议)
rdt1.0:完全可靠信道
发送方
接收到数据后,制作package并发送
接收方
接收到数据后,解析并发送给上层
rdt2.0:考虑比特受损
- 有肯定确认(positive acknowledgement)、否定确认(negative acknowledgement)
- 又称自动重传请求(Automatic Repeat reQuest)协议,需要差错检测、接收方反馈、重传
发送方
- 收到上层数据,制作package(包括检验码)并发送
- 开始等待,若接收到数据并发现是个NAK,重新发送;否则等待上层数据
接收方
接收到数据,如果损坏就发送NAK,否则把数据给上层并发送ACK
rdt2.1、2.2:考虑ACK和NAK损坏
-
引入分组序号(sequence number),1比特
-
2.2利用可能出现的冗余(duplicate)ACK代替NAK
-
发送方:
- 发送的序号为0或1,因此两个等待上方数据状态有01两种,等待确认信号的状态也有01两种
- 等待确认时只有不损坏且序号正确才能转换状态去等待上层数据
- 2.2去掉NAK后,等待确认时要确认是序号对应的ACK
- 接收方:
- 接收的序号为0或1,因此两个等待下方接收数据状态有01两种
- 2.1中如果损坏发回NAK,如果没损坏但序号不对发送上一序号的ACK
- 上述冗余ACK引出2.2的处理,不管损坏还是序号错,都发送上一序号的ACK
- 但是不明白为什么2.1发送的是NAK/ACK和checksum,难道不该发01嘛
rdt3.0:考虑比特受损&丢包
- 引入倒计数定时器(countdown timer)
发送方
- 发送数据后启动定时器
- 等待确认时同时响应定时器终止,重新发送包并重启定时器
- 收到正确的确认后关闭定时器,等待接收上层的下一状态数据
- 等待上层数据时接收冗余数据分组(可能因为时延被接收方当作ACK丢包并重发),不做处理
接收方(同rdt2.2)
流水线:GBN(回退N步)
-
上述均为停等协议,对信道(channel)的利用率(utilization)太低,引入流水线传输,不等确认便开始下一个包的发送,需要加序号和缓存(未按序接收的)
-
GBN引入窗口长度限制发送方流水线发送的分组,又称滑动窗口协议(sliding-window protocol)
base
,基序号,是窗口最前,是最早未确认分组的序号N
,窗口长度,整个窗口为,窗口内,要么包没确认,要么没发送nextseqnum
,下一个序号,是窗口未发送的包的开始序号,即 这段都是未确认的, 是未发送的
发送方
- 起始
base=nextseqnum=1
,发送方仅有一个状态 - 收到上层的数据包,在窗口未满时不断发送包并更新
nextseqnum
,窗口满了则向上层拒绝数据(或缓存)- 发送包时若是窗口最前端,启动定时器
- 定时器到期重新发送 的所有包
- 收到损坏数据不予理会,收到正确数据窗口移动(根据收到的ACK更新
base
),如果窗口内已经没有需要发送的包,停止定时器,否则重启定时器,这是一种累积确认(cumulative acknowledgement)
接收方
- 只按序接收,只维护
expectedseqnum
- 注意区分
expectedseqnum
和ACK的确认值
流水线:选择重传(SR)
-
Selective Repeat
-
为解决GBN的大量重传,接收方引入窗口和对应缓存
发送方
base
改为sendbase
,窗口不同处在于 间可能有已经确认的包- 每个分组有自己的逻辑定时器,可用单个硬件定时器模拟多个逻辑定时器
- 收到ACK后如果在窗口内则标记接收,如果是
sendbase
则更新sendbase
至未确认的最小分组 - 其他与GBN类似
接收方
- 维护一个窗口
- 接收窗口内的失序分组,缓存至前序分组都被收到,一批分组按序交给上层
- 接收到窗口之前的分组,重新确认那个分组
- 重新确认的存在表明接受和发送方窗口不一定是一致的,最坏情况是两个窗口完全错开,因此
拥塞控制(Congestion Control)
- 区分流量控制:拥塞控制侧重网络环境通过控制发送方减轻网络负担,流量控制侧重接收端控制发送方不会overflow对面的缓存
- 表现:丢包、长时延
三种情况研究拥塞的影响
情况1:2v2,1无穷缓存路由器
- 发送速率, 接收速率,链路容量
- 分组速率接近容量时时延巨大,缓冲区再大也不能解决实质问题
情况2:2v2,1有限缓存路由器
- 应用层发送速率, 运输层发送速率(包含重传)(又称供给载荷offered load), 接收速率,链路容量
路由器有空间才发送
路由器没空间丢包,仅确认丢包后重发
- 发送方重传补偿因缓存不足丢失的分组,加重了阻塞
- 随 增加 会趋近于
实际:路由器可能重传未丢失分组
- 大时延带来的不必要重传会使得路由器链路转发不必要的分组副本
情况3:4主机4路由器两跳路径
一个主机(A)的速率增加会导致D到B的吞吐量趋于0
- 丢包时上游传输的带宽努力都白费了
拥塞控制方法
-
端到端拥塞控制(end-end):端系统只能观察网络行为得知拥塞(丢包loss、时延delay),无明确显式信息,TCP自行判断与处理
-
网络辅助(network-assisted)的拥塞控制:路由器向发送方提供显式反馈信息,比如简单就一个比特,或是复杂的指示最大主机发送速率
UDP
- 用户数据报协议,User Datagram Protocol
报文格式
应用数据:应用层的报文
长度:整个UDP报文段的字节数
原理
- UDP将从应用得到的数据附上源和目的端口号字段、长度、检验和,并发送给网络层;将网络层得到的数据解析交付给socket
- 无连接:指UDP发送报文段前没有跟对面运输层握手
- 差错检验功能:检查传输过程中比特是否变化,但也只能检测,无法恢复
- 可能因链路中的干扰或者存储路由器时引入问题
- 所有字(16bit)做循环加法,得到结果取反填入检验和
- 检验时将所有字加起来,结果应为
优点
- 在应用层更精细(finer)控制数据的发送
- 无需建立连接,也就不需维护连接状态
- 分组首部开销小
- 相比TCP没有拥塞控制、可靠数据传输等功能,时延小
缺点
- 极端情况下,大量分组溢出,丢包率高,达不到目的地,还会使TCP(因为拥塞机制)减小速率
- 无可靠通信(但可以在应用程序中实现)
TCP
- 传输控制协议,Transmission Control Protocol
连接
- 面向连接的(connection-oriented):发送数据前必须先握手,发送预备报文段(preliminary segment),双方初始化TCP连接相关的状态变量(state variables),总共三次握手(three-way handshake),其中第一次客户发送的报文段没有payload,第三次有
- 双全工服务(full-duplex service):连接建立后数据可双向流动(flow)
- 点对点(point-to-point):no multicasting,连接中只有一对主机
- 可靠、有序、流水线数据传输
报文结构
- 序号:报文段首字节的字节流编号,字节按MSS(最大报文段长度,Maximum Segment Size)分段
- 确认号:期望收到的对面的字节流编号,采用累积确认,是否丢弃乱序包由编程人员决定,实践中会保留
- 接收窗口:简写rcvr window,用于流量控制,指示愿意接受的字节数
- 注:捎带(piggybacked)确认,比如Telnet中,收到数据时不着急发送ACK,稍等一会若有数据需要发送,将ACK和这个数据一包发走
往返时间(round trip time)和超时
- 超时时间必须超过RTT,太短会导致不必要的重传,太长会放大丢包的影响
- :某个报文段发出(交给网络层)到收到ACK的时间,不考虑重传的包,然而会波动
- 估计RTT:每获得新 就更新, 推荐值 ,这是一种指数加权移动平均(exponential weighted moving average)
- 偏差RTT:估算 偏离 的程度, 推荐值
- 波动大时将估计RTT放大一些作为时间间隔,波动小时缩小一些,每得到新的 则更新公式:
可靠数据传输
- 无损坏、无间隙、非冗余、按序
- 类似SR,但只有一个定时器:
- 发送数据时没有定时器则开启
- 重传(只会重传最小未确认报文段)后开启
- 收到数据后如果还有没确认的报文段则开启,否则关闭
- 因为累积确认,所以可以直接用ack更新窗口开端(前面的包就算没有ack,对面也一定收到了,不需要考虑重传)
- 简化版的发送方状态图:
- 接收方的ACK,其中乱序时可能是冗余ACK也可能是填补了间隔开始部分的普通确认ACK:
flowchart TD
接收方 -- 收到期望序号 --> 延迟ACK等待下一个期望序号一段时间 -- 超时则确认 --> 发送ACK
延迟ACK等待下一个期望序号一段时间 --> 收到第二个 -- 立刻确认 --> 发送ACK
接收方 -- 收到乱序发送期望间隔最小序号的ACK --> 发送ACK
- 快速重传(fast transmit):超时重发可能时间较长,收到3个冗余ACK就重传(貌似是实践经验,2次更可能是乱序,3次以上更可能丢包)
流量控制(flow control)
- receiver controls sender, so sender won’t overflow receiver’s buffer by transmitting too much, too fast
- 接收方维护 在报文段中指示缓存空间
- 当没有缓存时发送一个字节的报文段,接收方清空缓存并包含新的rwnd
连接管理
- 客户请求建立连接,
SYN
置1
,随机化选择初始序号 - 服务器收到后选择自己初始序号,确认序号为客户的序号+1,
SYN
置1
,发送SYNACK报文段 - 客户收到SYNACK后分配缓存和变量,发送报文段(置确认序号为服务器初始序号+1),
SYN
置0
,可以加入数据了 - 为什么不是两次握手?各种延迟(比如传输已经关闭但数据还没到)、重传(传输完成后又建立一个)、乱序
- 客户打算关闭时发送置
FIN
为1
的报文段,服务器收到后回复ACK - 服务器打算关闭时发送
FIN
为1
的确认报文段,客户收到后回复ACK - ACK都收到时两台主机资源释放
客户:
graph
CLOSED -- 发送SYN尝试建立连接 --> SYN_SENT -- 接受SYNACK发送ACK --> ESTABLISHED -- 发送FIN等待关闭连接 --> FIN_WAIT_1 -- 接收ACK --> FIN_WAIT_2 -- 接收FIN回复ACK --> TIME_WAIT -- 等待30s --> CLOSED
服务器:
graph
CLOSED -- 套接字监听 --> LISTEN -- 接受SYN发送SYNACK --> SYN_RCVD -- 接收ACK --> ESTABLISHED -- 接收FIN发送ACK --> CLOSE_WAIT -- 发送FIN --> LAST_ACK -- 接收ACK --> CLOSED
拥塞控制
-
receiver controls sender, so sender won’t overflow receiver’s buffer by transmitting too much, too fast
-
性质:加性增,乘性减,AIMD,Additive Increase Multiplicative Decrease,当TCP发送方感受到端到端路径无拥塞时就线性的增加其发送速度,当察觉到路径拥塞时就乘性减小其发送速度
-
:发送方维护的拥塞窗口长度
-
:慢启动阈值
-
发送速率
慢启动(Slow Start)
-
超时: ,重传分组,进入慢启动状态
-
ACK冗余: ,进入快速恢复状态
慢启动状态
- 初始,每确认一个报文段 ,即以指数增长
- 超过:进入拥塞避免状态
快速恢复状态
- 冗余ACK:
- 得到新的ACK:
拥塞避免
得到新的ACK:
TCP Tahoe & TCP Reno
上面给的是Reno,Tahoe不管是超时还是3个冗余都是恢复到慢启动开始指数增长,到阈值线性增长
宏观吞吐量(throughput)
窗口长度w
高带宽路径的平均吞吐量
公平性
吞吐量和应等于 ,指数增长会使得和超过R(直线沿45°走),引起丢包,减小窗口,和减少(直线沿丢包的那个点与远点的连线走)