运输层
这里主要讲的是在运输层几个比较重要的技术,即多路分解和复用,可靠数据传输原理和拥塞原理。
1. 多路复用/分解
先给出官方定义,将主机间交付扩展到进程间交付被称为运输层的多路复用和分解。多路分解就是在运输层接收到来自网络层数据后,根据运输层报文特殊字段的信息,将运输层报文段的数据交付到正确的套接字中。多路复用就是在运输层接受到套接字数据后,根据套接字的不同,生成运输层报文特殊字段(用于分解),然后将报文发送到网络层。通俗来说,多路复用和分解可以让不同进程的报文来使用相同的运输层协议(TCP,UDP)运输报文。
如图,运输层通过多路复用和分解,实现数据的正确交付。
下面这句话引用自计算机网络自顶向下方法,可以加深我们的理解:
尽管我们在因特网运输层协议的环境下引入了多路复用和多路分解,认识到下列事实是重要的:
他们与在某层(在运输层或别处)的单一协议何时被位于接下来的较高层的多个协议使用有关。
那么如何实现多路复用和分解呢?
需要两个条件:
- 每个套接字有唯一的标识符(也就是端口号)
- 也就是前面讲的,运输层报文的特殊字段(包含源端口号和目的端口号)
根据运输层协议的不同,UDP和TCP的报文中的特殊字段不同。
补充:
- 套接字接口的作用,把来自进程的数据传输到运输层,并且把来自运输层的数据传送的特定的进程。
- 每一个套接字分配一个端口号用来作为套接字的标识符。
- 运输层报文的格式基本如下所示:
下面具体讲一下UDP和TCP的多路复用和分解。
1.1 UDP的多路复用/分解
在UDP中一个套接字是由一个二元组全面标识的,二元组中包含了一个目的IP地址和目的端口号。
举个例子:假设现在有A,B,C三个主机,A和B同时通过2333端口号与C主机的3333端口号通信,这是A和B的目的端口号都是3333,所以他们通过相同的套接字进入相同的进程。这里的源端口号是用来从C向A,B发送报文时使用的。
1.2 TCP的多路复用/分解
TCP中的一个套接字是有四元组标识的,即目的IP地址,目的端口号,源IP地址和源端口号。
如图很好展示了TCP如何来识别套接字。
2. 可靠数据传输原理
首先要明确,我们真实的网络环境会发生比特差错和丢包的。
可靠数据传输主要包含以下几个技术,差错检验,肯定确认(ACK),序号,定时器,回退N步,累计确认,选择确认等等。
注意: 我这里讲的是,可靠数据传输用到的一些技术方法,并没有具体TCP或UDP报文。
下面分别介绍上面的技术:
2.1 差错检验
差错检验用来检测报文在传输的过程中有没有发生错误,具体的方法还没学到。
2.2 肯定确认ACK(positive Acknowledgment)和否定确认(NAK)
简单地说,就是接受端每当收到一个正确报文,就发送一个ACK来告诉发送端他收到了。而如果报文在运输的过程中出现了错误(比如差错检验没通过),这时接收端就会丢弃刚刚收到的报文,并且发送一个NAK来告诉发送端重新发送上一个报文。
注意: 由于我们真实的网络环境是会发生比特差错的,所以ACK和NAK也会发生错误。举个例子,现在 接收端正确收到了报文A,并且发送了一个ACK,不过由于传输中发生了错误,ACK变成了NAK。这时接受端收到了错误的ACK,由于不确定,发送端会重新发送上一个报文,但是这时接受端已经正确接受到了报文,所以接受端再次接受的正确的报文A时,接受端就发生了冗余(他自己没办法判断是不是冗余)。解决这个问题这个问题的方法就是接下来要讲的序号。
2.3 序号
序号就是给每一个发送报文附上一个递增的序号,同时返回的ACK上也包含这个序号,表示此序号的确认。通过序号就可以完美的解决2.2出现的问题,根据序号的不同接受端就可以准确的判断报文是不是相同。
在TCP中,初始序号是由计算随机计生成,而返回的ACK的序号是报文的编号加上报文数据部分的字节数。分送端第二次发送的报文的编号,则是由上一次的ACK指定。
其实,我们现在可以只用ACK来确认,在接受端收到受损报文后,发送上一个报文ACK,当接收端再一次收到ACK时(冗余ACK,对一个报文的ACK接收端到多次ACK),他就知到报文受损了,所以他重新发送报文。下面只使用ACK。
2.4 定时器
定时器的设定是因为在真实的网络环境中,会出现丢包的情况。
举个例子,假设现在发送端向接受端发送了一个报文A,考虑一下两种情况:
- 报文A,在发送的途中丢失了
- 接受端收到了报文了,但是返回的ACK丢失了
以上的情况都会导致发送端收不到ACK,于是我们可以设定一个定时器和一个超时间隔,当发送方在指定的超时间隔内没有收到ACK后,发送端就重新发送报文A。
2.5 流水线技术
到现在为止,我们讨论的运输都是发送一个数据,返回一个ACK,然后在发送一个数据,这样的方式叫做停等协议。但是如果数据运输的时间比较长的话,停等协议的信道利用率是非常低的。所以引入了流水线协议,即一次可以发送多个报文。如图a是停等协议,图b是流水线协议。
使用流水线协议会带来以下的影响(参考Top-Down,这里的逻辑我没怎么理清):
- 必须增加序号的范围,因为每个输送中的的分组(不计算重传的)必须有一个唯一的序号,而且有多个在输送中的未确认报文。
- 协议的发送方和接收方两端也许不得不缓存多个分组。发送方最低限应当能缓冲哪些已发送但未确认的分组,如下面们讨论的那样,接收方或许也需要缓存那些以正确接受的分组。
- 所需序号范围和对缓冲的要求取决于数据传输协议如何处理丢失,损坏及延时过大的分组。解决流水线的差错恢复有两种基本方法是:回退N步(Go-Back-N,GBN)和选择重传(Selective Repeat,SR)。
2.6 回退N步
流水线技术,可以使我们不用等待上一个发送报文ACK,就可以发送新的报文。但是我们不能无限制的发送新报文,所以规定了一个数字N(也叫窗口长度,把N个报文称为窗口),作为最大的已发送还未确认报文的数目。如图
发送端的功能:
- 接受上层的调用
- 发送数据时,已发送还未确认的报文最多不超过N。只有当现在的报文被确认后才能发送新的报文(在图上的表现就是,把窗口右移)。
- 超时后,把现在窗口中所有的报文所有的已经发送还未确认的报文重新发送一遍。
接收端的功能:
- 接收到的报文序号正确时,发送一个ACK。
- 接收到的报文序号不正确时,不发送ACK。
- 采取累计确认的方法,即ACK是对他以及他之前所有报文的确认。
如图下面的窗口的大小为4,当出现超时后,发送端重新发送所有的报文。
2.7 选择重传
GBN可以提高信道的利用率,但是它也会到来一些问题。当窗口的长度N比较大的时候,前面报文的丢失会导致后面所有报文的重传,这样显然效率不高。于是有了选择重传。
选择重传就是接受端将那些失序到达的报文,接受并且发送一个ACK。所以他采取的不是累计确认,而是一个ACK确认一个报文。在发送端只有接收到每一个发送报文的ACK,才确切的知道报文已经发送。下面描述发送端,和接收端的功能。
发送端:
- 接受上层的调用
- 发送端维护一个大小N的窗口(从第一个发送未确认报文开始,大小为N),第一个报文接受的ACK是窗口右移。
- 超时时,发送端重新发送窗口N中,那些发送但未确认的报文。
接收端:
- 只要有报文到达,就发送ACK。
如图展示了选择重传协议的作用:
3. 拥塞控制原理
拥塞控制主要有两种方法:
- 端到端的拥塞控制,在运输层实现,TCP的拥塞控制。
- 网络辅助的拥塞控制,路由器向发送方提供关于网络的拥塞情况。
参考文献:计算机网络:自顶向下方法