[总结]文件传输模型之文件中转

写在前面

最近一个多月一直在弄文件传输的组件。最近也有个基本的样子了,这里算是一个简单总结吧。

中转模型

文件传输底层使用开源的c++通信组件hp-socket(Pullserver,pullClient)。感兴趣的可以搜一下。

废话不多说,进入正题

首先,所有的客户端必须首先登陆服务器,在服务器进行注册,在服务器端维护一个客户端标识与客户端信息的映射关系,比如客户端信息类ClientInfo。

//代码片段
ClientInfo
{
      IntPtr connID;
      string ip;
      ushort port;
}

则服务端,就需要有这样一个类似Dictionary<string,ClientInfo>的字典。在客户端A给客户端B转发数据的时候,可以从这个映射关系中找到对方。

登录过程

在客户端登录成功后,就可以发送文件了。

包头信息说明

TransferId:传输id,标识在同时传输多个文件时,是不同的传输。

TransferType:传输类型

TransferCommand:传输命令

MD5:检验值(md5或者hash,越短越好,算法越快越好)

FileName:文件名。

FileRelativePath:传输文件夹时用到,文件夹中的文件,需要用到相对路径,接收端根据接收路径+相对路径进行保存文件夹中的文件。

Size:文件或者文件夹总大小,将总大小抛给应用层,计算传输速度。

currendIndex:当前传输包的索引,也是读取文件第几个包的索引。

PkgCount:总共多少个包。接收端可以根据当前索引和包总数,来判断是否传输完成,或者在断点续传的时候用到。

From:发送端标识

To:接收端标识

BodySize:每次传输的body大小。

自定义协议

固定包头+Body

每次包都要遵循该协议,服务器收到包后,要进行解析,根据包头中bodysize取出这次的数据Data。

断点续传

在接收端,每次接收到包,写入文件的同时,将包头信息写入本地文件(ini也好,xml文件也好)。然后发送端,再次发送该文件的时候,首先会发送请求包,接收端根据该文件的包头信息和ini文件中的信息,比对md5是否相同,发送方是否相同,如果相同,则将CurrentIndex+1,响应给发送端。发送端就可以直接从CurrendIndex+1的位置继续读取文件包进行发送。

总结

该组件前前后后大概一个多月,里面业务比较复杂,需要考虑的到的东西还是比较多的,目前实现,同时传输多个文件,多个文件夹,断点续传功能。但多文件和多文件夹同时混合发送仍有问题。还有客户端A给客户端B发送文件的同时,客户端B给客户端A发送,仍有问题。

通过该组件的设计,也收获不小,对业务能力也是一种考验。对tcp通信有了更深入的学习。

本文只是分享一下思路,感兴趣的可以搜一下hp-socket。

posted @ 2015-02-08 12:04  wolfy  阅读(2089)  评论(0编辑  收藏  举报