传输层为两个不同主机上的应用程序之间提供逻辑通信机制
网络层为两个主机之间提供逻辑通信
主要提供两种协议TCP和UDP:
多路复用:从多个套接字收集数据,添加首部封装数据,然后将报文段传递到网络层的过程叫做多路复用
多路分解:将收到的数据传递到对应的套接字的过程叫做多路分解
UDP套接字有两个属性标识(目的IP地址和目的端口号)
来自不同的IP地址/端口号的IP报文段可以导向同一个套接字
UDP具有以下特点:
数据段可能丢失、传递失序的报文到应用程序
无连接:在UDP接收者发送者之间没有握手、每个UDP数据段的处理独立于其他数据段
UDP的首部有八个字节,由四个字段组成,每个字段长度为两个字节,长度是指首部和数据的总长度
在UDP中在进行校验和的计算过程中,会引入UDP的伪首部,伪首部的作用仅仅是为了计算校验和
UDP校验和差错检测
目标:对传输的数据进行差错检测
- 按位相加
- 回卷
- 取反
TCP套接字由四个属性表示(源IP地址,源端口号,目的IP地址,目的端口号)
Rdt1.0 完全可靠信道上的可靠数据传输
RDT2.0:具有bit错误的通道上的可靠数据传输
具有bit错误是指:在接收方接收的报文段中的数据可能会和发送方发送的数据不一致,一般通过差错校验机制来判断是否发送错误
什么是停等协议?发送方发送一个报文,然后等待接受方的响应
RDT2.1:发送方处理混乱的ACK/NAK
在2.0中,可能会出现发送的ACK/NAK出现错误因此出现了RDT2.1,通过分组上来添加序号来判断是否最新的分组
RDT2.2:无NAK的消息协议
不用 NAK, 如果上个报文接收正确接收方发送 ACK
接收方必须明确包含被确认的报文的序号
发送方收到重复 ACK 将导致和 NAK一样的处理: 重发当前报文
在2.1中可以去掉NAK,只通过ACK来表示可以减少信息类型数量
RDT3.0:具有出错与丢失的信道
发送的消息除了出错之外,还有可能完全丢失,需要设置定时器当超过一定时间后重新发发送分组
a)正常发送
b)一号报文丢失
d)发送方超时间隔过短
定量看:rdt3.0的性能
例如: 1 Gbps链路, 15 ms 端到端传输延迟, 8000bit 报文, 计算网络利用率?
停等浪费了物理资源的使用
发送方:
在分组头中规定一个k位的序号【0-2k-1】
“窗口”, 允许的连续未确认的报文【长度为n的序列】
ACK(n): 确认所有的报文直到(包含)序号n - “累积ACK”
对第一个发送未被确认的报文定时
超时(n): 重发窗口中的报文n及以上更高序号的报文(只有一个定时记录最早的未被确认报文的发送时间)【窗口下沿设置定时器】
接收方
重发最高序号的分组ACK
- 发送0-3号报文后,等待ACK
- 0和1号ACK到了,窗口移动到2号,并发送4和5号
- 由于二号报文丢失了,于是接收方丢弃345,并且都回复ACK1,要求传二号报文
- 发送方的二号报文窗口下沿超时,重发2345报文
4567
收到了023的ACK,接收方发送的ACK是按序列顺序进行发送的,说明1号分组发送成功,只是ACK1丢失。所以需要重传最大的ACK+1的分组及其后面的分组
和GBN的区别,发送方的窗口出现间隙
发送方接收方的窗口不一致
发送方收到ACK时,若在窗口范围内,标注为被接收,如果接收后使得窗口某一部分被填满了,则窗口向右边滑动
接收方如果接收分组在窗口内,就发送ACK
失序分组暂时缓存
有序分组:交付上层,窗口滑动
接收方收到窗口左边的分组,必须发送相应的ACK,否则发送方的窗口会被卡住
二号在传输过程中丢失了,接收方缓存345
发送方因为超时重传二号包
序号是有限的,窗口大小小于或等于序号空间大小的一半
报文段结构
新版的首部格式:
CWR:CWR 标志与后面的 ECE 标志都用于 IP 首部的 ECN 字段,ECE 标志为 1 时,则通知对方已将拥塞窗口缩小;
ECE:若其值为 1 则会通知对方,从对方到这边的网络有阻塞。在收到数据包的 IP 首部中 ECN 为 1 时将 TCP 首部中的 ECE 设为 1.;
URG:该位设为 1,表示包中有需要紧急处理的数据,对于需要紧急处理的数据,与后面的紧急指针有关;
ACK:该位设为 1,确认应答的字段有效,TCP规定除了最初建立连接时的 SYN 包之外该位必须设为1;
PSH:该位设为 1,表示需要将收到的数据立刻传给上层应用协议,若设为 0,则先将数据进行缓存;
RST:该位设为 1,表示 TCP 连接出现异常必须强制断开连接;
SYN:用于建立连接,该位设为 1,表示希望建立连接,并在其序列号的字段进行序列号初值设定;
FIN:该位设为 1,表示今后不再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位置为 1 的 TCP 段。每个主机又对对方的 FIN 包进行确认应答之后可以断开连接。不过,主机收到 FIN 设置为 1 的 TCP 段之后不必马上回复一个 FIN 包,而是可以等到缓冲区中的所有数据都因为已成功发送而被自动删除之后再发 FIN 包;
TCP序号和确认
问: 接收方如何处理失序的数据段
答: TCP规范没有明确规定, 由编程人员处理
TCP往返时延的估计和超时
如何设置 TCP 超时值?
比 RTT长;但 RTT变化
太短: 不成熟的超时、不必要的重传
太长: 对数据段丢失响应慢
首先指定RTT的初始估计值
每次接收到样本RTT,和预测RTT指数加权平均
TCP在IP不可靠服务之上创建rdt服务
流水线技术处理报文段
累积确认
GBN和选择性重传的综合
TCP不会像GBN一样直接将失序报文报文丢掉,而是像SR一样缓存。
发送方不会重传一大段报文,只重传没有被确认的
TCP使用累计确认,为了降低开销只使用单个重发定时器,和GBN类似
TCP 使用单个重发定时器
触发重发:
——超时事件
——重复确认
超时触发重传存在问题:超时周期往往太长
重传丢失报文之前要等待很长时间,因此增加了网络的时延
接收方收到乱序的包就会发送重复ACK,两次的重复ACK可能是重新排序造成的,三次的重复ACK可能是丢包造成的
两次重复ACK肯定是乱序造成的
丢包肯定会造成三次重复ACK
假定通信双方如下,A发送4个TCP 报文段给B,编号如下,N-1成功到达,因此A收到B的ACK(N),重组到达顺序,观察收到ACK(N)的数量
A 发送至 B
A方发送顺序->N-1,N,N+1,N+2
B方到达顺序
由于累计确认机制,如果发生乱序
① N-1,N,N+1,N+2 -> A收到1个ACK (N)
② N-1,N,N+2,N+1 -> A收到1个ACK (N)
③ N-1,N+1,N,N+2 -> A收到2个ACK (N)
④ N-1,N+1,N+2,N -> A收到3个ACK (N)
⑤ N-1,N+2,N,N+1 -> A收到2个ACK (N)
⑥ N-1,N+2,N+1,N -> A收到3个ACK (N)
如果N丢包
N-1,N+1,N+2 -> A收到3个ACK (N)
N-1,N+2,N+1 -> A收到3个ACK (N)
TCP 乱序 有2/6 的概率会造成A收到三次冗余ACK(N);
而如果N丢了,则概率为100%A
基于以上的统计,当A接收到三次 冗余ACK(N)启动立马快速重传N可快速修复一个丢包的恶劣影响。
而如果A接收到二次冗余ACK(N),则说明是乱序造成的,已经传送到了B
图自小林coding
在上图,发送方发出了 1,2,3,4,5 份数据:
- 第一份 Seq1 先送到了,于是就 Ack 回 2;
- 结果 Seq2 因为某些原因没收到,Seq3 到达了,于是还是 Ack 回 2;
- 后面的 Seq4 和 Seq5 都到了,但还是 Ack 回 2,因为 Seq2 还是没有收到;
- 发送端收到了三个 Ack = 2 的确认,知道了 Seq2 还没有收到,就会在定时器过期之前,重传丢失的 Seq2。
- 最后,收到了 Seq2,此时因为 Seq3,Seq4,Seq5 都收到了,于是 Ack 回 6 。
所以,快速重传的工作方式是当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。
TCP连接的接收方有一个接收缓冲区:应用程序可能从这个缓冲区读出数据很慢
(假设 TCP 接收方丢弃失序的报文段)
连接:通信双方通信之前确认彼此的存在,确认一些通信需要的参数,做好一些资源的准备,如开辟缓冲区等。通信过程中需要维护连接状态的存在,当结束通信时通过合理的步骤逐步终止通信过程释放资源。
- 客户端发送不带数据的、SYN标志位为1、指定客户端随机初始序号的数据报请求连接建立
- 服务器接收,回复ACK=1、SYN=1、指定服务器的随机初始序号
- 客户端接收,回复ACK=1、SYN=0,可携带数据
为什么是三次握手?
为什么不是两次
- 三次握手双方都要对信道的可靠性做至少一次确认
- 服务器和客户端都要对双方选择的初始序号进行确认,这样双方才能使用该序号+1来发送数据
- 信道不可靠, 但是通信双方要要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足"在不可靠信道上可靠地传输信息"这一需求所导致的
为什么不选择更多次
- 下层信道是不可靠的,无法完全保证连接建立好了
- 从效率出发,保证三次即可
假设发送方和接收方为ab
其实很简单, 1.a->b, 这个时候没有任何状态, 2. b->a, b给a发东西, 说明收到了a的东西, 证明了a的发送能力是没问题的,同时证明了b的接收能力也是没有问题的。 如果到这里就结束了, 那么a的接收能力和b的发送能力就没办法保证了。如果再加上3. a->b , 证明了a收到了b的发送, 那么b的发送能力也是好的, a的接收能力也是好的。这样a和b的接收发送的能力都是好的, 就没必要再次证明了
关闭是双向的
多个终端发送数据的时候由于链路带宽的限制若发送过多数据会导致分组丢失和排队时延较长,为了解决这个问题TCP引入了拥塞控制
流量控制:不让接收方来不及接收报文【发送方不会淹没接收方】
拥塞考虑的是网络的情况
发送方通过调整发送行为来对拥塞进行反应,发送速率是通过调整发送窗口的大小实现的
流量控制中发送方的窗口大小是由接收方返回的接收窗口字段进行调整
引入新机制:拥塞窗口【CongWin】,发送窗口=min{拥塞窗口,接收窗口}
TCP拥塞控制的重点就是通过对网络的感知动态的调整拥塞窗口
发送方通过丢包事件感知拥塞->超时、三次冗余ACK
TCP发送方在丢失事件后降低发送速率【减小拥塞窗口】
采用三个机制
- 慢启动
- 对拥塞事件做出反应
- AIMD【加性增,乘性减】
- 刚启动时,将拥塞窗口设为一个最大报文段
- TCP以2的指数方式增加速率直到产生丢失事件,或者达到某个阈值ssthresh
每个RTT中拥塞窗口翻倍
- 超时事件
- 拥塞窗口置为1MSS,进入慢启动,到达阈值线性增长
- 三次冗余ACK
- 拥塞窗口减半 + 3,然后线性增长
- 表明网络有传输的能力
- 最初是指定的
- 随着传输的进行动态变化,设为丢包之前的一半
- 发生丢包事件:拥塞窗口减半
- 每个RTT拥塞窗口增加一个MSS
慢启动状态:拥塞窗口呈2的指数倍增长
拥塞避免状态:拥塞窗口线性增长快速恢复状态:每收到一个重复的ACK,拥塞窗口+1【网络数据包守恒原则】
无论何种状态,超时事件发生则转移到慢启动状态,阈值降为丢包前窗口的一半,拥塞窗口变为1;
无论何种状况,收到3个重复的ACK,转移到快速恢复状态,阈值降为丢包前的一半,拥塞窗口变为新阈值+3
拥塞窗口到达阈值就变为拥塞避免状态
快速恢复状态收到新的ACK转移到拥塞避免状态,并且将拥塞窗口设为阈值
TCP 平均吞吐量
假设忽略慢启动
假设在丢失发生时,设W是窗口大小
如果窗口为 W, 吞吐量是 W/RTT
丢失发生后, 窗口降为 W/2, 吞吐量为 W/2RTT.
平均吞吐量为0 .75 W/RTT
以太网帧的数据段的最大长度为1500 byte
1500 byte 减去 IP数据报的首部20 byte,IP片的数据长度最大为1500 - 20 = 1480 byte
IP的数据段 为 UDP报文端 : 8(UDP首部) + 8192 = 8200 byte
8200 / 1480 = 5 … 800 所以应该划分 6 个IP数据报片
对于IP片偏移,其单位为8 byte 需要除以8,如下: