3-传输层
[TOC]
本节内容:
-
理解基本理论、基本机制
- 多路复用、多路分用
- 可靠数据传输
- 流量控制
- 拥塞控制
-
掌握Internet传输层协议
- UDP:无连接传输服务
- TCP:面向连接的传输服务
- TCP拥塞控制
3.1-传输层服务
计算机网络MOOC_301_传输层概述.pdf
传输层协议为运行在不同Host上的进程提供了一种逻辑通信机制

逻辑通信机制:两个进程仿佛是连接在一起的,不需要了解传输介质,物理距离,经过多少路由器等
端到端的传输层协议:
-
发送方:将应用递交的消息分层Segments,并向下传输给网络层
-
接收方:将接收方的segments组装成消息,上交给应用层
传输层与网络层区别
-
网络层提供主机之间的逻辑通信机制
-
传输层提供应用进程之间的逻辑通信机制
3.2-多路复用和多路分用
为什么要进行多路复用/多路分用?
如果某层下一个协议直接对应多个协议/实体,那么需要复用/分用

如上图,主机2的P1和P2进程同时与1、3主机建立连接,那么需要正确地交付进程,这时候需要多路分用。
多路分用:传输层依据头部信息将收到的Segment交给正确的Socket,即不同的进程
多路复用:在发送之前为每块数据封装上头部信息,交给网络层。
分用
主机接收IP数据报(datagram)
- 每个数据报携带源IP、目的IP
- 每个数据报携带传输层的段(segment)
- 每个Segment携带源端口号和目的端口号
- 主机接收Segment后,传输层提前IP、端口,将segment导入对应socket

无连接分用
- 利用端口号创建Socket
DatagramSocket mySocket1 = new DatagramSocket(99111);
DatagramSocket mySocket1 = new DatagramSocket(99222);-
UDP的Socket使用二元组标识(IP+port)
-
主机收到UDP段
- 检查段中目的端口号
- 将UDP段 导向 对应Socket
-
来自不同源的数据包被导向同一个Socket(只要目的IP+端口是一样的)
例:
创建一个6428端口的服务器Socket

面向连接的分用
- TCP的Socket使用四元组标识
- 源IP、端口
- 目的IP、端口
- 接收端创建多个进程,相当于多个Socket用于区分连接
例:
多进程的服务器,假设你不仅在ping服务器,还使用http连接

例:多线程web服务器:
进程创建多个线程,操作系统会自动创建并分配socket

3.3-UDP
UDP: User Datagram Protocol [RFC 768]
特点:
- 基于Internet IP协议
- 能够复用分用
- 简单的错误校验功能(Checksum)
为什么需要在传输层检验:
- 路由器转发过程中也可能出错
- 链路层功能专一一点比较好
Best Effort服务:UDP段可能丢失、不按顺序到达
无连接:
- 不需要建立握手
- 每个报文独立于其他段
UDP优点:
- 延迟少:无需建立连接,eg: DNS
- 实现简单:无需维护连接状态
- 头部开销小(8字节,TCP20字节)
- 没有拥塞控制:上层应用可以更好的控制发送时间
- 可以自己造轮子【doge】

用途:
- 容忍丢失、速率敏感服务,如流媒体
- DNS、SNMP
UDP上实现可靠数据传输
- 应用层增加可靠性机制
- 应用层增加错误恢复机制
UDP校验和
目的:检查UDP段在传输中是否发生错误
发送方计算校验和:
- 将段分成 16-bit * n 个整数
- 计算所有整数的和,进位移动后相加,按位取反,得到校验和
- 将checksum放入对应字段
接收方计算校验和,并对比校验和,如果不相等就丢掉。(相等还有错误的概率比较小)

3.4-可靠数据传输的基本原理
概述
什么是可靠:不错、不丢、不乱
为什么需要可靠数据传输协议(rdt):
- 可靠数据传输对各层都很重要
- 网络Top-10问题
- 信道的不可靠特性决定了可靠数据传输协议的复杂性
服务角度

实现角度

接口
- rdt_send:被上层应用调用,将数据交给rdt以发送给对方
- udt_send:被rdt调用,在不可靠信道上向接收方传输数据(IP协议)
- rdt_rcv:当数据包接收时调用
- deliver_data:被rdt调用,向上层应用交付数据
程序就是状态机
利用状态机(Finite State Machine, FSM)刻画传输协议:

rdt1.0
特点:
- 底层信道完全可靠(理想结构)
- 接收方和发送方的FSM独立

发送方直接发,接收方直接收就行了
rdt2.0
特点:
- 信道会产生位错误
- 差错检验
- ACK/NAK
- 重传
可以使用校验和检测错误
- 确认机制(Acknowledgements, ACK):接收方告诉发送方正确收到
- NAK:接收方告诉发送方数据包发生了错误
- 发送方收到NAK后,重传分组
基于此协议的rdt协议称为ARQ(Automatic Repeat reQuest)协议

发送方每次发送一个数据包都需要等待接收端确认信号,这称为停等协议
缺陷:
- 如果NAK/ACK自己错了怎么办?
rdt2.1
如果NAK/ACK自己错了怎么办?
- 为ACK/NAK增加校验和(如hamming码
- 增加额外的控制消息
- 重传
- 产生重复分组
如何解决重复分组问题?
- 序列号(Sequence Number):发送方给每个分组增加一个序列号
- 接收方丢弃重复分组


rdt2.2
无NAK消息协议:只使用ACK
- 接收方告知最后一个正确分组
- ACK消息中加入正确分组的序列号
- 发送方接收到重复ACK的消息后,相当于收到NAK,重传

rdt3.0
特点:
- 信道可能错误、丢失,校验和也会错误
- 增加定时器
解决方法:发送方等待一段时间,如果没收到反馈,那么重传

性能分析
rdt能正确工作,但性能不好
eg: 1Gbps链路,15ms端到端传播延迟,1KB分组
发送方利用率:发送方发送时间百分比
即,在1Gbps链路上,每30ms才能发送一个分组,即, 说明网络协议限制了物理资源的利用

3.5-流水线机制滑动窗口协议
流水线机制:一次发3个,或者一次发5个,可以提高效率

实现流水线协议:
- 更大的序列号范围
- 更大的存储空间用来缓存分组

滑动窗口协议
滑动窗口协议:Sliding-window protocol
窗口:允许使用的序列号范围,尺寸为N,表示最多能等待确认N个消息
滑动窗口:随着协议的运行,窗口在序列号课件向前滑动

GBN
Go-Back_N协议:
发送方:
-
假定序列号有 k-bit,空间
-
窗口尺寸N,最多允许N个分组未确认

-
ACK:确认序列号 1-n 的分组均已被正确接收
-
为未确认的分组设置定时器
-
超时:重传序列号大于等于N,还未收到ACK消息
-
发送方扩展FSM

接收方:
- 没有缓存
- ACK:简单发送最高序列号的正确分组的ACK
- 乱序到达的分组:
- 直接丢弃(没有缓存)
- 重新确认整理好最大的、按序到达的分组
eg

练习题
数据链路层采用 GBN 协议,发送方已经发送了编号为0~7的帧。当计时器超时时,若发送方只收到0、2、3号帧的确认,则发送方需要重发的帧数是多少?分别是那几个帧?
解:3号表示0-3号都接收了,4567没有接收,需要重发:4、5、6、7
SR
GBN缺陷:重传时会重传很多数据包,导致不必要的开支
Selective Repeat协议:
- 接收方对每个分组单独确认,设置缓存机制,可以接收乱序到达的分组
- 发送方只重传没收到的ACK分组
- 为每个分组设置定时器
- 发送方窗口:
- N个练习序列号
- 已发送未确认的分组

SR困境
序列号比较小,窗口比较大时,会发生错误,于是我们规定

3.6-TCP
3.6.1-概述
特点:
- 点对点,沿途路由器不会影响连接状态
- 可靠的、按序的字节流
- 流水线机制
- tcp拥塞控制和流量控制机制设置窗口尺寸
- 缓存,连接双方都有缓存
- 全双工:同一连接中能传输双向字节流
- 面向连接
- 通信双方在发送数据之前必须建立连接
- 连接状态只在两端维护
- 连接包括:双方主机缓存、连接状态变量、Socket
- 流量控制机制
TCP段结构

序列号:segment中第一个字节编号,建立TCP连接时,双方随机选择序列号
ACKs:希望收到的下一个字节的序列号,
累计确认:该序列号之前的所有字节均被正确接收
TCP规范中没有规定如何处理乱序到达的Segment,需要自己实现,(手动@cs144)
3.6.2-TCP可靠数据传输
RTT和超时
设置定时器和超时时间:稍大于RTT。避免不必要的重传和丢失时反应过慢。
估计RTT:
SampleRTT: 测量从段发出到收到ACK的时间
ExtimatedRTT: 测量多个RTT,求平均值
超时时间 =
RTT变化大,边界就变大
测量RTT变化值:
一般
超时时间:
发送方事件
- 从应用层收到数据
- 创建Segment
- 序列号
- 开启定时器
- 设置超时时间
- 超时
- 重传引起超时的Segment
- 重启定时器
- 收到ACK
- 确认此前未确认的Segment
- 更新SendBase
- 如果窗口还有未确认的分组,重启定时器
TCP重传示例



快速重传机制
如果Sender收到对同一数据的3个ACK后,会假定该数据之后的段丢失,Sender会在定时器超时之前进行重传

3.6.3-TCP流量控制
流量控制:发送方不会发太多,避免淹没接收端

Buffer中可用空间
= RecvWIndow
= RecvBuffer - [LastByteRecv - LastByteRead]
接收方在头部字段将RecvWindow告知发送方,发送方限制自己已发送未ACK数据量不超过RecvWindow尺寸。
如果RecvWindow = 0,发送方会发送很小的字段,避免死锁。
3.6.4-TCP连接管理
TCP传输数据之前需要建立连接
- 初始化TCP变量
- Client:连接发起者
- Server:等待用户连接请求
三次握手:
- SYN:客户机向服务器发送SYN段
- SYNACK:服务器收到SYN,答复SYNACK段,服务器分配缓存,告知客户端
- ACK:客户端收到SYNACK,反馈ACK段,可能包含数据

3.7-拥塞控制原理
网络Top-10问题之一
拥塞(Congestion):发送主机太多以至于网络无 法处理,表现为路由器缓存溢出导致的分组丢失,以及路由器缓存排队导致的分组延迟过大

3.7.1-拥塞的成因
场景1-无限缓存
假设有两个Sender和两个Receiver,一个无限缓存的路由器

因为无限缓存,分组不会丢失,此时没有重传。
吞吐率随着增大,线性增长,直到达到最大throughput:
随着路由器中缓存增多,时延增长,快接近时,时延快速增长

场景2-缓存有限
此场景路由器有有限的buffer,Sender会重传分组
表示重传的数据

- 情况a:Sender能够获知路由器buffer信息,空闲时才发,(理想goodput)
- 情况b:丢失后重发
- 情况c:分组丢失或定时器超时后重发,变得更大,有效传输更低

多跳网络

分组丢失时位于传输上游的所有传输都被浪费

3.7.2-拥塞的方法
端到端拥塞控制:
- 网络层不需要显式地提供支持
- 端系统通过观察loss、delay判断拥塞
- TCP采用
网络辅助控制:
- 路由器反馈网络拥塞信息
- 简单的拥塞指示
ATM ABR拥塞控制
ABR:available bit rate
- 弹性服务
- 如果发送方路径 underloaded,使用可用带宽
- 如果发送方路径拥塞,将发送速率降到最低
RM:resource management cells
- 交换机设置RM cell位(网络辅助)
- NI:rate 不允许增长
- CI:拥塞指示
- RM cell 由接收方返回给发送方
- ER:速率字段
- 拥塞交换机将ER设置得更低
- 发送方获知路径支持最低速率
- EFCI:拥塞交换机将其设为1
- 若RM cell前面的data cell的EFCI,那么发送方在返回的RM cell中置为CI

3.8-TCP拥塞控制
Sender限制发送速率:
拥塞变量:CongWIn >= LastByteSent - LastByteActed
Bytes/Sec
感知网络拥塞:
Loss事件 = timeout 或者 3个重复ACK
发生 loss事件后发送方降低速率,加性增,乘性减(AIMD)
AIMD:逐渐增加发送速率,谨慎检测可用带宽,直到发送loss

慢启动SlowStart
TCP建立时指数性增长,避免浪费网络资源

初始速率虽然很慢,但是攀升速度快

Threshold变量
用来将指数增长转变为线性增长
当CongWin得到Loss事件前值一半时设置为其一半

以上方法比较保守,之后映入Series Reno变量
Loss事件处理
3个重复ACK:COngWin减半,线性增长
Timeout:CongWin设为1个MSS,指数增长直到达到Threshold
TCP拥塞控制算法
源码:https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_cong.c
