传输层
传输层的概述
传输层位于应用层和网络层之间,为运行在不一样主机的应用进程提供了逻辑通讯。从应用程序的角度看,经过逻辑通讯,运行不一样进程的主机好像直接相连同样。缓存
传输层协议是在端系统实现而非路由器中实现,在发送端,传输层将应用层传输来的报文分割成分组,每一个分组添加上传输层协议的首部,这些分组被称为报文段,以后,传输层把报文段传递给网络层处理,网络层处理以后再发送出去。服务器
因特网传输层协议
- UDP:UDP为应用程序提供了一种不可靠,无链接的服务,UDP没法保证数据无缺完好地交付给接收方。
- TCP:TCP为应用程序提供了一种可靠,面向链接的服务。TCP相对于UDP多了可靠数据传输服务、拥塞控制、流量控制等功能。
无链接传输:UDP
UDP的优点
- 无需创建链接
- 实现简单
- 头部开销少
- 没有拥塞控制机制,应用层能够更好控制流量和传输速率
UDP校验和
目的:检测报文段是否传输过程当中发生反转。性能
- 校验和的建立:发送方将报文段的内容视为16-bit整数,将全部整数相加(若是有进位,则将进位数字加到最后)以后按位取反。
- 校验和的校验:计算收到的报文段的校验和,若是和原校验和进行比对。若是不相等,则出现错误;若是相等,表明没有检测出错误(不表明没有发生错误)。
可靠数据传输原理
rdt1.0
底层信道彻底可靠,不发生错误,不发生丢包。server
过程
- 发送方:发送方传输层等待上层调用、上层调用以后发送分组。
- 接收方:接收方传输层等待下层调用、下层调用以后接受分组交付给上层。
rdt2.0
底层信道可能发生错误,但不会发生分组丢失。blog
过程
-
发送方生命周期
- 发送方传输层等待上层调用、上层调用以后发送分组。
- 等待接收方发送的ACK或者NAK。
- 当接收到ACK后,发送下一个分组;接收到NAK以后,从新发送该分组。
-
接收方队列
- 接收方传输层等待下层调用、下层调用以后接受分组。
- 接收到分组后,使用校验和来检测是否发生错误。
- 若是发生错误,向发送方发送NAK;若是没有发生错误,向发送方发送ACK,同时将分组交付给上层。
rdt2.1
若是ACK/NAK发生错误,则发送方重传该分组,但会出现重复分组的问题,为了解决重复分组的问题,使用rdt2.1.
过程
-
发送方
- 发送方传输层等待上层调用、上层调用以后发送分组,附带序列号0或1。
- 等待接收方发送的ACK或者NAK。
- 当接收到ACK后,发送下一个分组,若是上一次发送的序列号为1则这次发送0,若是上一次是0则这次发送1;接收到NAK或ACK/NAK发生错误以后,从新发送该分组,序列号和上一次同样。
-
接收方
- 接收方传输层等待下层调用、下层调用以后接受分组。
- 接收到分组后,使用校验和来检测是否发生错误。
- 若是发生错误,向发送方发送NAK;若是没有发生错误且收到的分组与预期的分组序列号一致,向发送方发送ACK,同时将分组交付给上层;若是收到的分组与预期的分组序列号不一致,向发送方发送ACK。
-
注:
-
什么是预期的分组序列号?
若是上一次接收方将分组序列号为1的分组交付给上层,则0上它这次预期的分组序列号,若是上一次接收方将分组序列号为0的分组交付给上层,则1上它这次预期的分组序列号。
-
当收到的分组与预期的分组序列号不一致,为什么发送ACK?
收到的分组与预期的分组序列号不一致说明发送方发送了重复的分组,且该分组已经被交付给上层,接收方发送ACK目的是告知发送方发送一下个新的分组。
rdt2.2
取消掉NAK,在ACK中加入被确认分组的序列号
过程
-
发送方
- 发送方传输层等待上层调用、上层调用以后发送分组,附带序列号0或1。
- 等待接收方发送的ACK或者NAK。
- 当接收到ACK后,发送下一个分组,若是上一次发送的序列号为1则这次发送0,若是上一次是0则这次发送1;接收到与预期序列号不一样的ACK或ACK发生错误以后,从新发送分组,序列号和上一次同样。
-
接收方
- 接收方传输层等待下层调用、下层调用以后接受分组。
- 接收到分组后,使用校验和来检测是否发生错误。
- 若是发生错误或者收到的分组与预期的分组序列号不一致,向发送方发送和上一次序列号同样的ACK;若是没有发生错误且收到的分组与预期的分组序列号一致,向发送方发送带这次序列号ACK,同时将分组交付给上层。
rdt3.0
信道即会发生错误,也会丢失分组,添加定时器机制
过程
-
发送方
- 发送方传输层等待上层调用、上层调用以后发送分组,附带序列号0或1,启动定时器。
- 等待接收方发送的ACK或者NAK。
- 若是超时,则重传并重启定时器(此过程多是分组丢失也多是ACK丢失)。
- 当接收到预期序列号ACK后,中止计时器,发送下一个分组,启动定时器,若是上一次发送的序列号为1则这次发送0,若是上一次是0则这次发送1;接收到重复ACK或ACK/NAK发生错误以后,什么也不作,继续等待预期的ACK。
-
接收方
- 接收方传输层等待下层调用、下层调用以后接受分组。
- 接收到分组后,使用校验和来检测是否发生错误。
- 若是发生错误或者收到的分组与预期的分组序列号不一致,向发送方发送和上一次序列号同样的ACK;若是没有发生错误且收到的分组与预期的分组序列号一致,向发送方发送带这次序列号ACK,同时将分组交付给上层。
流水线机制和滑动窗口
rtd3.0性能较差,因此引入流水线机制。
滑动窗口协议
滑动窗口定义了容许使用的序列号范围,窗口的尺寸为N,表明最多有N个等待确认的消息。
GBN滑动窗口协议

如图所示,窗口的左端是已经发送而且获得ACK的分组,窗口内黄色的是已发送但未ACK的分组,绿色是能发送的分组,白色是暂时不可发送的分组。
过程
-
发送方
- 发送方传输层等待上层调用
- 若是有窗口中有可用的序列号,则发送分组,并将黄色部分向后移动,若是如今发送的是窗口的第一个序列号,则启动计时器。
- 若是超时,重发全部黄色的分组。
- 若是收到ACK,该ACK附带一个序列号为N,将窗口向右移动,移动到N+1。若是此时没有发出去的分组,则中止计时器,若是已经有发出去的分组,则重启计时器
- 若是收到错误ACK,什么也不作。
-
接收方
- 接收方传输层等待下层调用、下层调用以后接受分组。
- 若是序号为n的分组正确且有序到达,则发送序列号为n的ACK。
- 其他状况下,丢弃该分组,并发送最近收到的有序的分组的序列号的ACK
SR协议
接收方可以缓存乱序分组,因此接收方也有一个滑动窗口。
过程
-
发送方
- 发送方传输层等待上层调用
- 若是有窗口中有可用的序列号,则发送分组,并将黄色部分向后移动。对每次发送的分组都开启一个单独的计时器
- 若是某个计时器超时,则重发那个分组。
- 若是接收到了ACK,将接收到ACK的分组标记一下,若是该分组是窗口内最小的,将窗口向右滑动。
-
接收方
- 接收方传输层等待下层调用、下层调用以后接受分组。
- 若是该分组乱序,则缓存该分组,若是该分组有序到达,则交付上层。
- 发送ACK
面向链接的传输:TCP
TCP报文段
序号与确认号
序号与确认号是TCP报文段中最重要的部分,TCP将传输的数据看做是字节流,并隐式地为每一个字节编号。报文段中的序号即是这次传输的数据段的的首字节的字节流编号。确认号是指接收方累积确认过程当中最小没有接受到的序号。
例如,主机A向主机B发送500000字节的数据,TCP将数据分割为500个报文段,每一个报文段中含有1000字节的数据,报文段的首序号为0。则第一次发送的报文段的序号为0,第二次为0+1000=1000,第三次为1000+1000=2000。假设第一个报文段到达主机B,主机B就收到了0-1000的数据,这时最小没有收到的数据为1001,则主机B向主机A发送确认号为1001的报文段。若是主机A发送的第二个报文段丢失而第三个报文段到达主机B,则主机B缓存上第三个报文段,继续向主机A发送确认号为1001的报文段。若是主机B收到了再次发送的第二个报文段,则将报文段与缓存中的数据拼接,发出确认号为2001的报文段。
冗余ACK
何时会出现冗余ACK?
- 乱序:发送方序号大的数据报先于序号小的数据报到达接收方,接收方根据累积确认原则发送最小没有接收到的序号,这时便会产生冗余ACK。
- 丢包:序号小的数据报丢失,序号大的数据包没有丢失,这种状况实际上就是乱序。
定时器
什么时候启动定时器?
- 当发送报文时没有定时器启动时启动定时器。
- 当超时重传以后启动定时器。
- 当收到一个有效确认报文且此时还有未被确认的报文段时启动定时器。
流量控制
链接的两端都会维持一个缓存队列,对发送方发送速率的控制防止其发送的数据超出了接收方的缓存队列的方法叫作流量控制。
接收窗口用rwnd来表示,接收窗口指的是缓存队列可用空间的大小,rwnd时动态变化的。接收方经过将rwnd传递给发送方来告知发送方还有多少的可用缓存空间。发送方要在整个链接的生命周期中确保未被确认的数据大小小于rwnd的大小。
若是接收方发来rwnd为0以后,接收方没有要发送的数据了怎么办?
若是没有任何额外的机制,那么发送方将不会知道什么时候接收方的缓存空间有空余,那么发送方将进入阻塞状态。实际上,发送方会持续发送1字节数据的报文段,若是接收方有空余,则能够发送rwnd不为0的响应报文段。
链接管理
三次握手
- 客户端发送一个报文段首部SYN比特为1的报文段,该报文段的序号是一个随机序号client_isn。
- 服务器收到该特殊的报文段后,分配缓存和变量,并向客户端发送一个报文段首部SYN比特为一、确认号为client_isn+一、序号为随机序号server_isn的报文段。
- 客户端收到该特殊的报文段后向服务器发送一个报文段首部SYN比特为0、确认号为server_isn+1的报文段。
为什么须要三次握手?
-
为了防止旧的链接使得整个链接形成混乱。
假设客户端向服务器发起了SYN报文段,以后因为网络阻塞客户端迟迟未到达服务端,以后客户端再次发送SYN报文段,这时,旧的SYN先到达了服务器,服务器认为客户端想以这个旧的报文段所携带的client_isn为序号,实际上这个是旧的报文段,已经不须要,那么客户端在第三次握手的时候就会告知服务器这个旧的链接终止。
-
从上文能够看出,三次握手是要分配必要的空间和变量,通知另外一端一些初始信息如序号。
四次挥手
客户端和服务器均可以主动断开链接,假设客户端主动断开链接。
过程
- 客户端发送一个特殊的TCP数据报,该数据包的一个标志为FIN设置为1。
- 服务器接收到该特殊的数据报,向客户端发送一个确认ACK的数据报。
- 服务器发送一个特殊的TCP数据报,该数据包的一个标志为FIN设置为1。
- 客户端接收到该特殊的数据报,向服务器发送一个确认ACK的数据报。
- 服务器收到确认数据报后关闭链接。
- 客户端通过定时等待后关闭链接。
为什么须要四次挥手?
客户端发出FIN,说明客户端已经没有了数据想要发送,因此主动断开链接。服务器即便接收到了FIN数据报,回复了ACK,如果服务器仍然在处理数据,而且还想发送,则它就不想关闭链接,若是服务器无数据要处理和发送了,则服务器也发送FIN数据报。
为什么须要定时等待?
数据传递过程当中,可能有一些应用数据报因为网络延迟迟迟不送达,定时等待时间为两倍的报文最大存活时间,通过定时等待时间以后,能够确保这次连接即便是延迟的数据报也没有了,防止本次链接的数据报传递给下一次新的链接致使数据混乱。
TCP拥塞控制
控制发送速率
经过网络的拥塞程度,动态调节拥塞控制窗口.
感知网络拥塞
加性增-乘性减
逐渐增长发送速率,当发生loss时,快速下降发送速率.
慢启动
当链接开始时,可用带宽可能远远高于初始带宽。因此,当链接开始时,拥塞窗口自1开始指数型增加。
慢启动转加性增
定义一个变量Threshold,当感知到拥塞发生时,Threshold设为发生Loss时拥塞窗口的值的一半。
- 发生超时:拥塞窗口降为1,慢启动。
- 3个重复ACK:拥塞窗口将为原来的一半,加性增。