`
longzhun
  • 浏览: 360662 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用不可靠的UDP设计可靠的文件传输协议

 
阅读更多

一、了解UDP协议一些具体细节

(可以直接跳到二、三看协议设计部分) 

UDP协议的工作是将待发送的网络数据流量压缩成数据报的形式,然后由服务器端发送给客户端。但是UDP协议是面向无连接的,它只提供最大努力的服务,也就是说UDP协议不带有在发送端进行数据报分组,在接收端再对收到的报文进行重新 排序和组装的功能。这样一来,当一个数据报从发送端出发后,系统是不对报文进行顺序编号和检查的,在接收端也就无法感知各个报文间的先后顺序和是否存在丢包。

 



 

这是UDP的报文首部的结构,其中前两行表 示为UDP协议规定的每一个UDP数据报必须带有的报头信息,UDP数据报头共由8个字节构成,报头的后面则是传输中的数据部分。UDP数据报的报头由4个域组成,分别为:源端口号、目的端口号、数据报长度以及校验和,其中每个域各占用2个字节。

 

UDP协议的主要特点有: 

1、UDP 是面向无连接的 

2、UDP是面向无连接的。 

3、UDP报文首部只有8个字节。 

4、传输的吞吐量不受传输速率调节算法的影响,这样就排除了对传输速度的限制瓶颈。 

5、UDP 是用的是尽最大努力交付,它不关心数据传输双方的连接状态,所以主机也就不用维护复杂的链接状态表。 

6、UDP 是面向报文的。对于应用程序交予传输层的报文,UDP协议不做报文的拆分或合并的操作,只是简单的在报文前添加首部并保留这些报文的原始边界,并选择合适的报文大小交给应用层处理。

 

由于UDP协议不需要进行确认的连接,所以编写基于 UDP 协议的文件传输应用程序比较简单。当然这也是UDP传输程序最大的缺点,那就是它不提供可靠地数据传输。使用UDP协议的数据传输中,发送端只是不停地向接收方发送数据,而接收方也只是简单的尽最大努力收集发来的数据,而不做数据完整性的检测。在这种机制下,如果数据传输过程中产生丢包,收发双方都是感知不到的。尤其在网络拥塞或线路噪声较大时,丢包、错包或是收到的报文不按顺序到达的情况会更加严重,影响传输效果。所以 UDP 协议在一些重要数据的传输场景下是被摒弃的。

 

综上所述,对于相对重要的数据传输,UDP 协议是不合适的,但对于一些不那么重要的数据,也就是即使偶尔出现丢包也不会有太大影响的,而且对传输速率要求较高的,如音频、视频数据等,UDP传输协议还是最好的选择。

 

二、 可靠的文件传输协议要求

具体要求: 

1)下层使用不可靠的UDP服务(即使用数据报方式的套接字); 

2)能够支持多用户并发访问和文件下载; 

3)下载的文件大小不应有限制;

 

首先,对于几个要求一一进行大致的回答:

 

我们知道UDP最大的优点是它的简单高效,而最大的缺点算是它无法保证数据传输的可靠性。所以,为了最大限度的发挥UDP的高速率,可以对UDP的不可靠传输进行适当的改进,以使数据的丢失率降到最低,在这种情况下本文可以对原有UDP增加一些控制机制,如丢包重发、错序重排等。如此一来,只需在应用层实现上述的可靠性机制,就能够在不太影响UDP传输速率和不占用过多系统资源的情况下,实现文件的可靠传输。

 

上边了解UDP特点时候我们说过,UDP是面向无连接的,这样一来就可以打破一对一连接的状态,使得一台服务器可以向多个客户端传输相同信息。

 

理论上说,UDP报头中报文长度字段是预留了两个字节,也就是说最大的 UDP 报文(加报头)的长度可以达到 65535 个字节。但是由于传输稳定性的需要,在实际传输中通常会对报文长度做一定限制,而很多情况下报文长度会被限制在8192个字节。但无论多大,对于一份任意大小的文件,我们都是可以通过切分成固定大小的N个报文然后将他们组成一组发送的。为了能让接受方知道某些数据报是一组的,还需要我们在发送某一文件分好组后首先发送一个装有相关信息的报文,如此来让接收方根据信息对接受报文进行检查。

 

三、 可靠的文件传输协议设计

(一)可靠性协议 

(可靠性协议这部分协议 参考论文《 基于UDP 的可靠文件传输协议设计与实现 》)

 

首先来设计最为重要的可靠性。在UDP增加报头前,我们先定义8个字节的协议头,为2个字节的数据包标识,2个字节的发送序号,2个字节的文件指针定位和2个字节的数据包中数据大小信息。数据包标志指明该数据包为文件数据包、确认包或者其它控制包,发送序号用来指明数据包的顺序信息,指针定位字节数据用来指明该数据包中数据被填写到文件的哪个位置,最后的大小信息也是用来向文件中读写数据时使用。

 

 

 

协议保证可靠性的大致流程是(先只考虑单对单情况下的单方向发送):

 



 

 

首先发送端发送一个文件信息报文,这个报文就是最简单的UDP报文,但是里面的信息很重要,记录着文件的大小,被分隔成的报文数,文件序号。发完这个信息包,发送端阻塞,等待接收端的回复报文才能继续。文件信息包被接收端接收以后使用确认机制确定是否接受这个文件,并把决定回馈给发送端。此时,发送端如果收到的是“确定接受”的结果,将会把这个文件的整组数据报全部发送过去,这里我们并不像最传统的可靠传输协议TCP协议一样,对于每个报文都要确认接收完才会对下一个报文进行处理,太没效率,遵守本协议的接收端在接收这组报文的时候将遵守错序重排机制,来对收到的这组报文进行按序号排序,期间可能序号不连续,不过没关系,接收过程只要保证序号从小到大即可。发送端发完所有报文延迟一点时间再发送一个结束报文,延迟时间是为了减少结束报文比数据报文还早被接收的情况,当然即使这种情况出现也不会破坏可靠性,只不过在结束报文之后的数据报文会被当做丢失的包被要求重发,降低效率。接收端接收到结束报文后按照一开始的文件信息包的信息和序列号做对比,把没有序列号的报文的信息传回给发送端,要求重新发送这些报文。发送端接到信息以后重发丢失的数据包。直到接收端拿到的报文和信息匹配,接受端就可以发回一个“接受完毕”的报文。这样发送端接受端再进行下一次文件传输。

 

在这个流程中有几个重要的机制保证流程的可靠性:

 

确认机制 

本系统接收方并非对任意数据包都进行确认,在下面的一些情况下会使用到该确认机制: 

1、接收方收到文件信息包时,要对是否接收进行确认。 

2、接收方收到结束包时要进行确认,然后检测该分组内数据包是否丢失。 

3、接收方收到全部数据包时要进行确认,以便结束文件的传输过程。

 

重发机制 

协议设计了两种重发机制:一种是自动重发机制,另一种是请求重发机制。自动重发机制是消息发送时启动一个定时器,如果在规定的一段时间内未收到接收方的确认消息,则断定这段时间内发送的报文已经丢失并进行重发。请求重发机制则是在接收方收到发送方发来的传输结束消息后,在接收方对收到的所有报文序号进行检测,如果发现某些序号的报文缺失,接收方主动请求重发缺失的序号对应的报文。具体实现设计如下所述:

 

1、自动重发机制 

通信发送方和接收方都维持一个自动重发定时器,在通信开始前会检查自动重发定时器是否启动,如果没有启动,就会启动这个定时器。如果在一个特定时间间隔内发送方没有收到来自接收方的任何确认消息,或者接收方没有收到发送方的结束检测报文。这时系统会将这个定时器归零,并将这段时间内发送的消息重发一遍,把记录重发次数变量加1。如果在规定的时间内依然没有收到对方的任何确认信息,则重新将定时器归0, 执行重发操作并将重发次数加1,如此循环,在重发次数未达到指定数据之前,直到收到对方的一个确认消息,然后停止自动重发定时器,将重发次数清 0;否则证明传输路径出现问题。

 

2、请求重发机制 

接收方记录着已收到数据包的序列以及未收到的数据包序列。当接收到分组结束包时,接收方就会启动定时器,检索该分组内未收到的数据包,如果数据包已全部接收到,则关闭定时器,进行下一个分组的传输。否则查找丢失 数据包的序号并依次发送请求重发数据包,在规定时间内接收发送方重发的数据包,然后定时器归 0,重新检索未收到数据包,并按上述情况做出反应,如此循环往复,直到最终完成该分组的传输过程。

 

协议的错序重排机制 

协议头结构中有2个字节的序号字段,当发送端接收到对端发送的确认接收报文后,开始读取文件数据块内容写入协议数据区,为每一个数据块编制一个序号,序号的最大值要求与接收端维护的一个为了实现错序重排机制的动态表长度一致。序号排满后,后面的报文会在下一个分组中进行发送。这时发送端 会根据当前分组下读取的数据块大小及起始位置填写协议头中的字段,最后将数据包发送出去。接收端起初会生成一个动态数组用来存储接收到的数据包序号,当接收端准备好接收文件后将数组的每一位置为无效,每收到一个数据包,就会读取其序号字段值并将数组相应位置为有效,然后将数据区的内容写入文件。这样即使由于网络状况导致数据包不能按序到达,接收端也能根据数据包位置字段和大小字段将数据写入文件。序号字段在收到结束包后用于检索动态数组启动请求重传机制。

 

(二)多用户并发访问和文件下载协议

 

前面我们说UDP是面向无连接的,这样一来就可以打破一对一连接的状态,使得一台服务器可以向多个客户端传输相同信息。

 

所以我们如何利用它来实现多用户并发访问和文件下载呢?本协议中,首先发送方会开辟一个空间,这个空间储存着发送端有的各个文件的序号和可能出现的接收方希望得到某个序号文件的ip地址端口号等信息。在发送端开始运作之后,就会有一个进程一直在监听是否有对某个文件的请求,如果有就把请求方的信息储存在这个空间里。假如请求某个文件的ip+端口只有一个,那么这个协议是没有实质性作用。然而一旦短时间内有大量的ip请求这个文件,那么在某次我们上边设计的可靠性协议的传输过程中,就可以好好利用这个时间差,下一段具体说明。除此之外还有一个很人性化的设计可以加入到这里,就是可以在监听到某次请求时向对方返回目前的服务器状况,比如对应文件的等待ip有多少,这样让接受方决定状况比较拥堵时候是否等一下再请求。

 

具体来说,我们每次发送文件信息报文时,在多个接收方请求的情况下将是一组一组发送的,把目前在等待空间的所有(或者限制一个上限个数10个)接收方都发送文件信息报文。收到的同意接受报文后把这些同意接受的信息记录下来,将文件报文组和发送完毕的报文同时发送给这些接受方,再把各个接收方返回的缺失报文记录下来,再重传。

 

非常重要的一点是,其实对于接受方来说在文件传输过程中并没有什么多余的动作,它要做的和只有他一个接收方的情况没有任何的不同,可能只是整个过程的流畅性会受影响。需要变动的主要是发送方,它在做好可靠性协议要求的几点之外,还要做好一系列的记录操作,保证整个过程不会乱套。

 

(三)针对下载的文件大小不应有限制设计的协议

 

回答问题时候其实就把思路讲完全了,对于一份任意大小的文件,我们都是可以通过切分成固定大小的N个报文然后将他们组成一组发送的。在每次组报文传输过程之前传输的文件信息报文也是这个过程之一,它记录了本次文件的大小,被分成的报文数量,每个报文的大小(通常确定的大小)。这种方法下,不管多大的文件都视作一定数量的报文,只要发送方和接受方在信息报文中确定了信息,文件大小就没有限制

 

所以,利用上边设计的可靠性协议、多用户并发访问和文件下载协议和针对下载的文件大小不应有限制设计的协议,我们就能实现一个可靠的文件传输协议,并满足以下要求:1)下层使用不可靠的UDP服务(即使用数据报方式的套接字);2)能够支持多用户并发访问和文件下载;3)下载的文件大小不应有限制。

--------------------- 

 

  • 大小: 59.2 KB
  • 大小: 7.2 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics