一、说明
经常有小伙伴在开发控制台、winform、WPF等C/S软件时,会有文件传输的需求。正好TouchSocket完美支持这个,所以给大家介绍一波。
二、程序集源码
2.1 源码位置
2.2 说明文档
三、安装
Nuget安装TouchSocket
即可,具体步骤详看链接博客。
四、特点
1.1 文件传输协议兼容性
RRQM文件传输使用的是特殊传输协议,与FTP,HTTP等协议完全不兼容,所以如果使用文件传输,则服务器与客户端必须均使用RRQM组件。
1.2 与FTP相比
因为RRQM使用的是特殊协议,所以性能、功能上要远强于FTP,且搭建简单,支持多通道传输等。
1.3 功能亮点
- 简单易用。
- 多线程处理。
- 高性能,实测传输速度可达1000Mb/s。
- 超简单的传输限速设置,1k-10Gb 无级调节。
- 超简单的传输速度、传输进度获取。
- 随心所欲的暂停、继续、停止传输。
- 系统化的权限管理,让敏感文件只允许私有化下载。
- RPC交互,让客户端和服务器交流不延迟。
- 基于事件驱动,让每一步操作尽在掌握。
- 超简单的断点续传设置,为大文件传输保驾护航。
- 已经上传的文件,再次上传时,可实现快速上传。
- 极少的GC释放。
演示: 可以看到,下图正在上传一个Window的系统镜像文件,大约4.2Gb,传输速度已达到800Mb/s,GC基本上没有释放,性能非常强悍(中间有稍微停顿,因为程序在获取文件MD5值)。
四、创建服务器
static void Main(string[] args)
{
TcpTouchRpcService service = GetService();
service.Logger.Message("服务器成功启动");
Console.ReadKey();
}
static TcpTouchRpcService GetService()
{
var service = new RRQMConfig()//配置
.SetListenIPHosts(new IPHost[] { new IPHost(7789) })
.SetMaxCount(10000)
.SetThreadCount(100)
.SetSingletonLogger(new LoggerGroup(new ConsoleLogger(), new FileLogger()))
.SetVerifyToken("File")//连接验证口令。
.BuildWithTcpTouchRpcService();//此处build相当于new TcpTouchRpcService,然后Setup,然后Start。
service.Handshaked += (client, e) =>
{
client.Logger.Message($"有客户端成功验证,ID={client.ID}");
};
service.Disconnected += (client, e) =>
{
client.Logger.Message($"有客户端断开,ID={client.ID}");
};
service.FileTransfering += (client, e) =>
{
//有可能是上传,也有可能是下载
client.Logger.Message($"有客户端请求传输文件,ID={client.ID},请求类型={e.TransferType},请求文件名={e.FileRequest.Path}");
};
service.FileTransfered += (client, e) =>
{
//传输结束,但是不一定成功,需要从e.Result判断状态。
client.Logger.Message($"客户端传输文件结束,ID={client.ID},请求类型={e.TransferType},文件名={e.FileRequest.Path},请求状态={e.Result}");
};
return service;
}
五、创建客户端
static void Main(string[] args)
{
TcpTouchRpcClient client = new RRQMConfig()
.SetRemoteIPHost("127.0.0.1:7789")
.SetVerifyToken("File")
.BuildWithTcpTouchRpcClient();
client.FileTransfering += (client, e) =>
{
//有可能是上传,也有可能是下载
client.Logger.Message($"服务器请求传输文件,ID={client.ID},请求类型={e.TransferType},文件名={e.FileInfo.FileName}");
};
client.FileTransfered += (client, e) =>
{
//传输结束,但是不一定成功,需要从e.Result判断状态。
client.Logger.Message($"服务器传输文件结束,ID={client.ID},请求类型={e.TransferType},文件名={e.FileInfo.FileName},请求状态={e.Result}");
};
client.Logger.Message("连接成功");
//第一个参数是请求路径,第二个是保存路径。
FileRequest fileRequest = new FileRequest(@"D:\System\Windows.iso", $@"Windows.iso");
fileRequest.Flags = TransferFlags.BreakpointResume;//尝试断点续传,使用断点续传时,会验证MD5值
FileOperator fileOperator = new FileOperator();//实例化本次传输的控制器,用于获取传输进度、速度、状态等。
fileOperator.Timeout = 60 * 1000;//当传输大文件,且启用断点续传时,服务器可能会先计算MD5,而延时响应,所以需要设置超时时间。
//此处的作用相当于Timer,定时每秒输出当前的传输进度和速度。
LoopAction loopAction = LoopAction.CreateLoopAction(-1, 1000, (loop) =>
{
if (fileOperator.Result.ResultCode != ResultCode.Default)
{
loop.Dispose();
}
client.Logger.Message($"进度:{fileOperator.Progress},速度:{fileOperator.Speed()}");
});
loopAction.RunAsync();
Metadata metadata = new Metadata();//传递到服务器的元数据
metadata.Add("1", "1");
metadata.Add("2", "2");
//此方法会阻塞,直到传输结束,也可以使用PullFileAsync
IResult result = client.PullFile(fileRequest, fileOperator, metadata);
client.Logger.Message(result.ToString());
Console.ReadKey();
}
六、总结
实际上,文件传输功能,在客户端之间也可以直接传输,服务器也可以直接向客户端主动Pull、Push文件。而且,对于TouchRpc而言,文件传输也仅仅是的其中一个功能而已,更多的功能请在说明文档获取。