在计算机网络通信运输层扮演的角色就是保证数据包的可靠性,即数据包的完整性及数据的发送顺序性
网络层与运输层的关系与差异
网络层
在五层模型中网络层位于运输层之下,它提供的是不同链路的主机与主机之间交付数据的IP服务,IP是不可靠的服务,即不保证数据的完整性和有序性,只负责主机和主机之间的数据传输,在网络层传输的数据称之为数据报。IP地址是网络层主机的唯一标识,网络层能够跨越不同的数据链路,在不同的数据链路之间实现IP数据包的传递,这一跨越数据链路的过程主要依靠路由控制实现,而路由控制通过对IP的多跳路由将数据包跳到相应被转发的路径,经过多次路由跳到达目的地,这个过程又要依赖路由器的路由表,它记录了下一步IP数据该转发给哪个路由器 多跳路由 这里是网络层多跳路由实现在不同链路的传递类比漫画:由于火车不能直达只能中途换乘,通过询问每个站的乘务员得到换乘路线,这里乘客就是IP数据包,乘务员就是路由器,火车就是数据链路运输层
运输层主要负责从网络层接收报文段实现不同主机上的进程之间的通信。
在发送端,它将应用程序进程接收的报文转换成运输层分组,运输层分组简称报文段,实现方法是将应用报文切分成小块并加上运输层首部就生成了运输层报文段。然后将报文段传递给网络层。
在接收端,网络层将数据包提取运输层报文段,将其交给运输层,运输层再将其发送给应用进程使用。
在运输层主要依赖的两种协议分别是UDP和TCP,两种协议的最基本任务就是将主机端的IP交付服务扩展为进程间的交付服务,这种扩展就是运输层的多路复用和多路分解
多路复用和多路分解
-
套接字:一个进程有一个或者多个套接字用于接收和发送数据包
-
多路复用:多路复用主要是收集各个进程的套接字中产生的数据块,并且为每个数据块加上首部信息形成报文段,然后将其传递到网络层中。
-
多路分解:多路分解主要是负责将运输层的数据交付到正确的进程套接字中
无连接运输:UDP
UDP是面向无连接,不可靠的运输协议,除了最基本的多路复用、多路分解及差错检测外,几乎没有对IP数据包增加别的东西。UDP从应用程序得到数据后,附加上多路复用和多路分解的源端口号和目的端口号后形成报文段交给网络层,网络再将其封装到IP数据报中,将其发送给接收的主机,达到主机后UDP使用报文段中的端口号将其交付给相应的应用进程,使用UDP的过程没有经过任何的握手,因此UDP是无连接的。DNS就是典型的UDP协议的应用,还有实时视频,网络语言电话等流式多媒体音频应用也是使用UDP,原因在于UDP性能较高,并且这类应用能容忍少量的数据包丢失。面向连接运输:TCP
TCP是面向连接的可靠的传输协议,即保证数据不会受到损坏或者丢失,并且能按照发送顺序交付,它主要通过三次握手、重传控制、拥塞控制、滑动窗口等机制保证数据传输的可靠性
三次握手
理解三次握手先需要明白TCP报文段各个字段的含义:- 源端口和目的端口:写入源和发送目的地的应用程序端口号
- 序号(Seq):TCP连接中传送的字节流中的字节都是按照顺序去编号的,报文段中Seq是这个报文段的字节流的首个字节编号
- 数据偏移:首部长度实际上指示了数据区在报文段中的起始偏移值
- 确认号(ack):期望收到下一个报文的数据流的首个字节编号。
- 窗口:告知接收端的缓存大小,以此控制发送端的发送速率,达到控制流量的效果
- 检验和:奇偶检验和,校验包是否有误
- TCP flags每一个标志位表示一个控制功能:
- URG: 紧急指针标志 1->有效 0->忽略
- ACK:确认号标志 1->有效 0->报文不含确认号信息,忽略确认号
- PSH:push标志 1->push标志有效,表面接收方接收后应对尽快交给应用程序 0->忽略
- RST:重置连接标志
- SYN:同步序号,用于建立连接过程,syn=1->建立请求或接受请求:syn=1并且ack=0时建立连接请求,SYN=1并且ACK=1时双方接受连接(这里画重点,下面TCP三次握手会多次使用)
- FIN:释放连接 1->发送方已经没有数据可发送,关闭本方数据流 0->连接仍然存在
TCP连接的建立时,双方需要经过三次握手,具体过程如下:
(1)第一次握手:Client进入SYN_SENT状态,发送一个的报文段中SYN=1表示请求建立连接,seq=x表示本次发送的字节流中首个字节的编号,第一次握手是不携带数据的,所以服务端下次肯定会响应ack=x+1
(2)第二次握手:Server端在收到SYN帧之后,会进入SYN_RCVD状态,同时响应报文段中 ack=x+1表示希望下次收到x+1的首字节编号的报文段,服务端的报文段中字节流中首个字节的编号 seq=y,ACK=1表示本次响应是有效应答,本次为响应连接请求所以SYN=1
(3)第三次握手:Client在收到Server的第二次握手SYN+ACK确认帧之后,首先将自己的状态会从SYN_SENT变成ESTABLISHED,表示自己方向的连接通道已经建立成功,Client可以发送数据给Server端了。然后,Client响应报文段中第一次握手发送报文段已经消耗了一个字节所以 seq=x+1,第二次握手中客户端已经收到了y编号的字节下次希望接收y+1的首字节编号的报文段所以ack=y+1,ACK=1表示有效应答
(4)Server端在收到Client的ACK帧之后,会从SYN_RCVD状态会进入ESTABLISHED状态,至此,Server方向的通道连接建立成功,Server可以发送数据给Client,TCP的全双工连接建立完成。
报文段的长度MSS
MSS报文段的最大消息长度,在三次握手时两端会将自己能接收的MSS写进TCP报文段首部中,两者之间选择最小的,建立连接后传输的数据会以MSS进行分割发送
重传控制
正常情况接收端会按照发送端发送报文段的序列号和数据长度,响应ack的报文段,确认应答号(ack)=系列号(seq)+数据长度(MSS) 但是难免消息丢失的情况发生,发送端在特定是时间间隔每天收到接收端的响应将会对消息进行重传,消息丢失有以下两种情况:对于消息丢失有以下几种措施
1、超时重传与超时间隔加倍
发送端在特定时间内没有收到接收端响应则会进行重发,这个特定时间在不同的网络环境会有所不同,如果发送端重发了报文段,依旧没有收到响应,接收端会将超时时间加倍,每一次重传都会将超时间加倍,直至超过一定的次数还未收到响应就会将连接断开
2、高速重传
在重传的过程中接收到会多次接收到相同的报文段,接收端会根据序列号判断是否需要接收该报文段,避免重发接收导致的丢弃动作
流量控制
窗口控制
TCP发送端每发一个报文段,就要等待确认接收端的响应,这样的效率比较低下,为了解决这个问题引进了窗口的概念。在窗口大小内,发送端无须等待确认接收端的响应 窗口不能越大越好,如果不根据两端的接收能力的对比会出现下面的情况 接收端和发送端可以在TCP报文段的首部将自己的接收能力填到窗口的选项中,再从两者中选择一个小的滑动窗口
滑动窗口内的数据都是未被响应的数据,滑动窗口以外是为发送或者已被响应的数据,下面是具体滑动窗口的控制详细图:窗口控制下的重传机制
假设发送端发送了1,2,3这三个报文段,接收端响应时1,2的响应报文段都丢失了,而3响应到达了发送端,那么也发送端知道接收已经积累了1,2,3的报文段,就无须重发1,2的报文段了,这种方式叫累计确认或累计应答。拥塞控制
慢启动
有了窗口,收发主机之间可以连续发送大量的数据,但是有些时候网络会成为收发数据的瓶颈,因为各种原因网络不好而出现拥塞,这时如果还大量的发送数据可能会造成网络瘫痪,TCP使用慢启动去控制发送数量
在建立连接后拥塞窗口cwnd的值被设置为1,代表着每次只能发一个报文段,每次成收到一次确认应答后,cwnd都会加1,每次发送报文段时将会与接收端的滑动窗口大小做比较,选择较小的作为发送窗口。随着包的往返,窗口将会以1,2,4,8...成倍的增加 窗口大小以指数增加,这样很有可能会造成网络的拥塞 如果我们让窗口以1,2,3,4,5...这样的方式增加的话能避免窗口过快增长,但是这样又太慢了,达不到快速高效: 为了解决这个过慢或过快的问题,我们可以把第一种方法和第二种方法结合起来。也就是说,我们刚开始可以以指数的速度增长,增长到阈值ssthresh 。当增长到阈值时,我们就不在以指数增长了,而是一个一个线性增长。所以最终的策略是:前期指数增长,到达阈值之后,就以一个一个线性的速度来增长。 但是由于TCP连接开始时是没有设置阈值的,拥塞窗口只会以指数增长,直到当遇到超时重传时,就将阈值设置为拥塞窗口的一半,然后拥塞窗口再初始化为1,这样再次发送报文段时就会先以指数增长然后再以线性增长,由于高速重传机制,当报文段丢失时重复的应答需要三次才会触发发送端的数据重发,慢启动阈值就会被设置为当前发送窗口的一半,紧接着发送窗口就被设置为当前慢启动阈值+3,这一过程如下图所示TCP以这种方式,让通信开始时网络吞吐量能逐渐上升,遇到网络拥塞时又能逐渐下降,而后又逐渐上升,TCP吞吐量能逐渐占据宽带
网友评论