IT
上一篇文章C# UDPSocket)异步传输文件(3,实现了多文件的传输和MD5校验,还显示了文件传输过程中的信息,在这一篇文章中,将介绍怎样实现传输文件的进度显示和实现选择保存文件路径。

         首先,来实现一个显示文件传输过程信息的控件,它需要显示文件的图标、名称、大小、已经传输了的大小、文件的传输速度和一个进度条,进度条可以很直观的看到文件传输的完成量。

要获得文件的图标可以用API,但是还有一个更简单的方法,就是Icon类的ExtractAssociatedIcon方法,看看它的说明:返回指定文件中包含的图像的图标表示形式,呵呵,是不是很方便啊。来看看这个控件的类视图:


 

接着,在请求发送文件的时候,要把图标也发送到接收端去,所以我们要在原来的TraFransfersFileStart类中多加一个Image属性。

    在文件的传输过程中,我们要知道接收或发送文件的一部分大小、文件是否接收或发送完成等很多不同的信息,所以在原有的文件发送类(UdpSendFile)和文件接收类(UdpRecieveFile)增加了几个事件,具体的事件就不进行过多的介绍了,大家可以下载源码来看。当收到文件的一个数据包或者发送文件的一个数据包,还有接收或发送完成的时候,我们就通过这些事件来更新显示发送或接收文件控件的信息,这样,我们就可以很清楚的了解到文件传输信息了。

    现在来看看文件传输的截图:
    开始发送:
 


接收文件:


 

    完成了:

 上一篇文章C# UDPSocket)异步传输文件(4,只实现了传输开始前拒绝接收文件,没有实现文件传输进行的时候取消传送,这篇文章中我们就来介绍怎样实现这个功能。

         在传输过程中取消文件的传送,有很多地方要考虑,最重要的就是要对数据的访问进行同步。当发送文件方取消发送时,我们要从文件发送列表中移除对应的发送文件管理类和移除传输控件,并且清理资源。在移除的时候,因为是异步收发信息的,也许其他地方还在申请使用这些资源,所以我们在移除的时候,不能让其他地方再访问他们,这里就要加上锁。清理发送文件管理类也一样,因为是异步读写文件的,我们清理的时候,需要等待正在读写的操作完成后才能进行清理,所以在发送文件管理类中加入了一个新的安全的Stream对象SafeStream,文件的读写都由他来操作。当接收方取消接收的时候,情形跟发送发一样,也需要进行类似的处理,这里就不多说了。

    在新的项目中,实现了传输没有完成时,文件的后缀名改为.tmp。还实现了当选择的存储文件的目录下有相同的文件时,接收的文件将会以文件名_1.rar这样的方式保存。

         在这一系列的文章中,发送方都是等到接受方返回接收成功信息后才开始传输下一个数据的,这就会出现一个问题,当接收方没有接收到数据或者接收方接收到了数据但是发送的接收成功的数据包发送方没有收到(丢包了),发送方就一直不会发送下一个包数据,这样文件传输就中断了,这个问题我们就留到下一篇来解决吧。
 

 

         文件传输过程的截图以前都发了,现在就看看取消发送的截图吧:

 

 上一篇文章C# UDPSocket)异步传输文件(5中,还遗留了一个传输文件最大的问题,就是传输过程中丢包,这样在文件传输过程中就会卡住了,这篇文章就来解决文件传输中的丢包问题,实现稳定的文件传输。

         检测丢包是一个很麻烦的问题,解决的方法可能也有不少,我采用的是在接受文件端来检测,当开始接收文件,收到一个数据包后,如果等待超过了一定时间后都没有收到数据包,就给发送方发送一个新的请求,要求继续发送文件,直到文件全部接收完成。具体的做法就是:

1、 ReceiveFileManager类中加入一个记录文件分块接收状态的列表Dictionary<int, bool>int表示文件分块的序号,bool表示是否已经接收,初始化为全部没有接受(false)。

2、 ReceiveFileManager类中加入一个Timer,用来检测收到一个包后,等待的时间是否超过了设置的值,超过就给发送方发送数据包,请求继续发送文件,需要发送的文件块序号为从Dictionary<int, bool>中查询出来的没有接收的文件块序号。

3、 如果Dictionary<int, bool>中的所有文件块已经收到(全部为true),文件就接收完成了。

按照以上的做法,就可以保证文件可以全部接收到了。其实也可以从发送方来处理这个问题,就是发送方发送一个包后,如果等待了一定时间没有接收到接受方的回复,就重发这个包,也许有时间,下次就换这种方式看看,大家也可以自己试试。具体的实现还是挺麻烦的,大家从源码中看吧。

在新的例子中,用了新写完的文件传输控件,外观漂亮了,控件的显示效率也提高了不少。

到现在为止,基本上实现了一个稳定的异步UDP(Socket)发送多文件的功能了,在实现中是通过MD5做文件校验的,当文件很大的时候,计算MD5比较慢,所以就感觉发送的时候有点卡,其实很多时候是不需要的(QQ传文件也没有验证的),我们可以把这个功能取消掉,用一个GUID来标识每一个不同的文件就行了。

下面来看看传输文件的截图:





posted on 2010-07-02 17:58  liufei  阅读(4459)  评论(2编辑  收藏  举报