传输层(基本大纲)
理解传输层服务的基本理论和基本机制
- 多路复用/分用
- 可靠数据传输机制
- 流量控制机制
- 拥塞控制机制
掌握Internet的传输层协议
- UDP:无连接传输服务
- TCP:面向连接的传输服务
- TCP拥塞控制
传输层服务和协议
传输层协议为运行在不同host上的进程提供了一种逻辑通信机制
(两个进程之间仿佛是直接连接的,不需要关心中间经过多少路由器、经过多少物理层的媒介)
端系统运行传输层协议
- 发送方:将应用递交的消息分成一个或多个segment(段),并向下传给网络层
- 接收方:将接收到的segment组装成消息,并向上交给应用层
传输层可以为应用提供多种协议
- Internet上的TCP
- Internet上的UDP
网络层和传输层的区别
- 网络层:提供
主机
之间的逻辑通信机制 - 传输层:提供
应用进程
之间的逻辑通信机制
- 位于网络层之上
- 依赖于网络层服务
- 对网络层服务进行(可能的)增强
举个例子
小明家四个孩子(应用进程)
给小红家四个孩子(应用进程)
写信(应用消息)
,小明和小红(传输层协议)
会帮孩子写好的信寄出去,从小明家房子(主机)
寄出,通过邮政服务(网络层协议 )
到达小红家房子(主机)
。
Internet传输层协议
可靠、按序的交付服务(TCP)
- 拥塞控制
- 流量控制
- 连接建立
不可靠的交付服务(UDP)
- 基于“尽力而为(Best-effort)”的网络层,不保证传输过程中一定可以送达,也不保证传输过程不丢失,没有做(可靠性方面的)扩展
两种服务均不保证延迟和带宽
的保障
多路复用和多路分用
分用如何工作
主机接收到IP数据报(datagram)
- 每个数据报携带源IP地址、目的IP地址
- 每个数据报携带一个传输层的段(Segment)
- 每个段携带源端口号和目的端口号
主机接收到Segment之后,传输层协议提供IP地址和端口号信息,将Segment导向相应的Socket
- TCP会去做更多的处理
无连接分用
利用端口号创建Socket
DatagramSocket mySocket1 = new DatagramSocket(99111);
DatagramSocket mySocket2 = new DatagramSocket(99222);
UDP的Socket用二元组标识
- (目的IP地址,目的端口号)
主机收到UDP段后
检查段中的目的端口号
将UDP端导向绑定在该端口号的Socket
来自不同源IP地址和/或源端口号IP数据包被导向同一个Socket(只要目的IP地址和目的端口号一样即可)
SP:源端口号
DP:目的端口号
面向连接的分用
TCP的Socket用四元组标识
- 源IP地址
- 源端口号
- 目的IP地址
- 目的端口号
接收端利用所有的四个值将Segment导向合适的Socket
服务器可能同时支持多个TCP Socket
- 每个Socket用自己的四元组标识
与UDP不同的是,两个具有不同源IP或源端口号的到达的TCP报文段将被重定向到两个不同的套接字。
多线程Web服务器
+
Q:不是说TCP不同的话,两端都必须是不同的进程吗,为什么在服务器端只是一个P4呢?
A:由于进程是一个耗费资源比较多的机制,现在我们可以让一个进程创建多个线程这个轻量级的进程机制,让线程和不同的TCP连接绑在一起,P4创建了3个线程
思考这三个问题:什么是多路分用和多路复用,为什么要使用多路分用和多路复用,怎么做多路分用和多路复用?
这篇文章介绍的十分详细 https://blog.csdn.net/ljianhui/article/details/21660629
UDP
基于Internet IP协议
- 复用/分用
- 简单的错误校验
- UDP把IP层服务暴露给应用层
“Best effort“服务,UDP段可能
- 丢失
- 非按序到达
无连接
- UDP发送方和接收方之间不需要握手
- 每个UDP段的处理独立于其他段
UDP存在的价值
- 无需建立连接(减少延迟)
- 实现简单:无需维护连接状态
- 头部开销少
- 没有拥塞控制:应用可更好地控制发送时间和速率
UDP的应用
常用于流媒体应用
- 可以容忍一些数据的丢失
- 对速率的要求比较敏感
还用于DNS、SNMP
UDP上实现可靠数据传输
- 在应用层增加可靠性机制
- 应用特定的错误恢复机制
UDP的报文格式
UDP校验和(checksum)
目的就是检测UDP端在传输中是否发生错误(如位翻转)
发送方
- 将段的内容视为16bit整数
- 校验和计算:计算所有整数的和,进位加在和的后面,将得到的值按位求反,得到校验和
- 发送方将校验和放入校验和字段
接收方
- 计算所收到段的校验和
将其与校验和字段进行对比
- 不相等:检测出错误
- 相等:没有检测出错误(但可能有错误)
1放到最后一位然后进位
可靠数据传输原理
可靠数据传输协议
- 可靠数据传输对应用层、传输层(TCP)、链路层都很重要
信道的不可靠特性决定了可靠数据传输协议(rdt)的复杂性
rdt:可靠传输协议
udt:不可靠传输协议
rdt_send()
:被上层应用调用,将数据交给rdt以发送给对方
udt_send()
:被rdt调用,在不可靠信道上向接收方传输数据
rdt_rcv()
:当数据包到达接收方信道时被调用
deliver_data()
:被rdt调用,向上层应用交付数据
Rdt1.0:可靠信道上的可靠数据传输
底层信道完全可靠
- 不会发生错误
- 不会丢弃分组
发送方和接收方的FSM(有限状态机)独立
Rdt2.0:产生位错误的信道
辨别位错误
- 利用校验和检测位错误
如何从错误中恢复?
- 确认机制(Ackonwledgements,ACK):接收方显式地告知发送方分组已正确接收
- NAK:接收方显式地告知发送方分组有错误
- 发送方收到NAK后,重传分组
基于这种重传机制的rdt协议称为ARQ(Automatic Repeat request)协议
Rdt2.0中引入新机制
- 差错检测
- 接收方反馈控制信息:ACK/NAK
- 重传
Rdt2.0:FSM规约
这里与rdt1.0不同,这里发送方有两个状态:等待上层调用和等待ACK/NAK控制消息
发送方:
当处在Wait for call from above状态时,有上层调用了,产生一个package,这时候要加上校验和生成SNK package,然后发出去。然后等待ACK或NAK的状态,重传回来的是ACK的话就等待下次上层调用,如果是NAK的话就要重传数据。
接收方:
下层有数据过来,收到一个package,判断这个分组是否有错误,如果有错误,反馈NAK给发送方,如果没有错误,从中提取数据向上层交付。
Rdt2.1
Rdt2.0中如果ACK/NAK消息发生错误或者被破坏了,这样的话导致Rdt2.0的机制就无法成功。
可以有几种选择
- 为ACK/NAK
增加校验和
,检错并纠错 - 发送方收到被破坏ACK/NAK时不知道接收方发生了什么,
添加额外的控制消息
,但是额外的消息也可能坏掉,所以不可行 - 如果ACK/NAK坏掉,发送方重传,如果简单重传,会产生重复分组
解决重复分组问题
- 序列号(Sequence number):发送方给每个分组增加序列号
- 根据序列号可以判断是新的还是重复的,重复的话就直接接收方丢弃重复分组
发送方
接收方
对比Rdt2.0
Q:为什么(0,1)两个序列号就够用了
A:因为采用的是停-等协议
状态数量翻倍,状态必须记住当前的分组序列号
接收方需判断分组是否是重复,当前所处状态提供了期望收到分组的序列号,接收方是无法知道ACK/NAK是否被发送方正确收到的
Rdt2.2:无NAK消息协议
去掉NAK消息协议,只使用ACK
- 接收方通过ACK告知最后一个被正确接收的分组
- 在ACK消息中显式地加入被确认分组的序列号
发送方收到重复ACK之后,采取与收到NAK消息相同的动作,重传当前分组
2.0与2.1区别就在于加入了序列号机制
Rdt3.0
前面的缺陷是如果接收方发回的ACK丢失了,那么发送方就会一直等待下去,这样协议就不能工作了,使用为了解决这个问题,rdt3.0使用增加定时器
的方法
流程示例
思考一下如何解决第四种情况,就是因为设置的延迟时间过短导致的ACK0和ACK1都发向了发送方的情况,发送方该如何处理呢?
但是Rdt3.0在性能方面差
流水线机制与滑动窗口协议
性能慢是因为在停-等机制中,这中间只进行了一个任务,而如果多个任务的话那要一个一个来,这导致了性能下降,使用流水线机制
,在停-等的过程中可以同时进行下一次发送,允许多个分组发出去,这样的话就可以提高性能。
流水线机制
允许发送方在收到ACK之前连续发送多个分组
- 原本两个序列号已经无法满足要求了,这时候需要更大的序列号范围
- 发送方、接收方需要更大的存储空间来缓存分组
滑动窗口协议
窗口
- 允许使用的序列号范围
- 窗口尺寸为N:最多有N个等待确认的消息
滑动窗口
- 随着协议的进行,窗口在序列号空间内向前滑动,比如1-10用完了,就该用11-20了等等
滑动窗口协议:GBN、SR
绿色代表已完成部分,黄色代表已经发出去但是还未反馈部分,蓝色代表可用的窗口数
GBN协议(Go-Back-N)
采用累积确认的机制,如果收到ACK(n)的话表示确认到序列号n(包括n)的分组均已经被正确接收了
- 可能收到重复的ACK
- 计时器
- 超时事件:重传序列号大于等于n,还未收到ACK的所有分组
GBN发送方的FSM
GBN接收方的FSM
ACK机制:发送拥有最高序列号的、已被正确接收的分组的ACK
- 可能产生重复的ACK
- 只需要记住唯一的expectedseqnum即可
在GBN中可能会产生乱序分组的情况,就是5号来了而3号还没回来,GBN的处理是
- 直接丢弃——>接收方没有缓存
- 重新确认序列号最大的、按序到达的分组
GBN示例图
SR协议(Selective Repeat)
GBN的缺陷:丢失后会重传N以及N以后的文件,这样使性能下降
那么SR协议的改进就是不使用累积确认机制,接收方对每个分组单个确认
,设置缓存机制,缓存乱序到达的分组
发送方只重传那些没收到ACK的分组
- 为每个分组设置定时器
SR协议多了一个接收方窗口
灰色
是我希望收到但是还没收到的,红色
是乱序到达的分组,蓝色
的是可以接受的序列号的范围
序列号的位数是k, 发送方窗口的尺寸, 接收方窗口的尺寸,序列号空间大小与窗口尺寸需满足 的关系