C#高性能大容量SOCKET并发(九):断点续传
来源:互联网 发布:欧弟 天天向上 知乎 编辑:程序博客网 时间:2024/05/22 00:07
上传断点续传
下载断点续传断点续传主要是用在上传或下载文件,一般做法是开始上传的时候,服务器返回上次已经上传的大小,如果上传完成,则返回-1;下载开始的时候,由客户端上报本地已经下载大小,服务器根据位置信息下发数据,因此上传下载协议都需要带Size大小,例如我们协议格式。
上传开始:
客户端->服务器
{
[Request]
Command=Upload
Dir=Dir #目录,全路径名
FileName=FileName #文件名(不包括路径)
}
服务器->客户端
{
[Response]
Command=Upload
Code= Error Code #错误码
Message=Message #如果出错,返回错误描述信息
FileSize=FileSize #已上传文件的大小,用于续传
}
因此在接收客户端上传请求时需要下发服务器上次接收到文件地址:
public bool DoUpload() { string dirName = ""; string fileName = ""; if (m_incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName) & m_incomingDataParser.GetValue(ProtocolKey.FileName, ref fileName)) { if (dirName == "") dirName = Program.FileDirectory; else dirName = Path.Combine(Program.FileDirectory, dirName); fileName = Path.Combine(dirName, fileName); Program.Logger.Info("Start upload file: " + fileName); if (m_fileStream != null) //关闭上次传输的文件 { m_fileStream.Close(); m_fileStream = null; m_fileName = ""; } if (File.Exists(fileName)) { if (!CheckFileInUse(fileName)) //检测文件是否正在使用中 { m_fileName = fileName; m_fileStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite); m_fileStream.Position = m_fileStream.Length; //文件移到末尾 m_outgoingDataAssembler.AddSuccess(); m_outgoingDataAssembler.AddValue(ProtocolKey.FileSize, m_fileStream.Length); } else { m_outgoingDataAssembler.AddFailure(ProtocolCode.FileIsInUse, ""); Program.Logger.Error("Start upload file error, file is in use: " + fileName); } } else { m_fileName = fileName; m_fileStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite); m_fileStream.Position = m_fileStream.Length; //文件移到末尾 m_outgoingDataAssembler.AddSuccess(); m_outgoingDataAssembler.AddValue(ProtocolKey.FileSize, m_fileStream.Length); } } else m_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, ""); return DoSendResult(); }
下载开始:客户端->服务器
{
[Request]
Command=Download
Dir=Dir #目录,全路径名
FileName=FileName #文件名(不包括路径)
FileSize=FileSize #客户端本地文件大小,用于断点续传
PacketSize=PacketSize #下发数据包大小,单位为KB,用于速度测试
}
服务器->客户端
{
[Response]
Command= Download
Code= Error Code #错误码
Message=Message #如果出错,返回错误描述信息
}
public bool DoDownload() { string dirName = ""; string fileName = ""; Int64 fileSize = 0; int packetSize = 0; if (m_incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName) & m_incomingDataParser.GetValue(ProtocolKey.FileName, ref fileName) & m_incomingDataParser.GetValue(ProtocolKey.FileSize, ref fileSize) & m_incomingDataParser.GetValue(ProtocolKey.PacketSize, ref packetSize)) { if (dirName == "") dirName = Program.FileDirectory; else dirName = Path.Combine(Program.FileDirectory, dirName); fileName = Path.Combine(dirName, fileName); Program.Logger.Info("Start download file: " + fileName); if (m_fileStream != null) //关闭上次传输的文件 { m_fileStream.Close(); m_fileStream = null; m_fileName = ""; m_sendFile = false; } if (File.Exists(fileName)) { if (!CheckFileInUse(fileName)) //检测文件是否正在使用中 { m_fileName = fileName; m_fileStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite); m_fileStream.Position = fileSize; //文件移到上次下载位置 m_outgoingDataAssembler.AddSuccess(); m_sendFile = true; m_packetSize = packetSize; } else { m_outgoingDataAssembler.AddFailure(ProtocolCode.FileIsInUse, ""); Program.Logger.Error("Start download file error, file is in use: " + fileName); } } else { m_outgoingDataAssembler.AddFailure(ProtocolCode.FileNotExist, ""); } } else m_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, ""); return DoSendResult(); }
多线程并发下载
断点续传的一个应用就是并发下载,做法是客户端起多个线程并发请求同一个文件,每个线程下文件的一部分,全部下载完成后,把每个数据块合并为一个文件。这个服务端和客户端协议都不需要修改,只是需要做下载逻辑的更改。
多线程并发上传
这个需要定义通讯来支持这个逻辑,主要是服务器要提供合并多个数据文件为一个文件的协议逻辑。
DEMO下载地址:http://download.csdn.net/detail/sqldebug_fan/7467745
免责声明:此代码只是为了演示C#完成端口编程,仅用于学习和研究,切勿用于商业用途。水平有限,C#也属于初学,错误在所难免,欢迎指正和指导。邮箱地址:fansheng_hx@163.com。
- C#高性能大容量SOCKET并发(九):断点续传
- DELPHI高性能大容量SOCKET并发(八):断点续传
- DELPHI高性能大容量SOCKET并发(九):稳定性问题解决
- Netty高性能大容量Socket并发
- C#高性能大容量SOCKET并发(一):IOCP完成端口例子介绍
- C#高性能大容量SOCKET并发(二):SocketAsyncEventArgs封装
- C#高性能大容量SOCKET并发(四):缓存设计
- C#高性能大容量SOCKET并发(三):接收、发送
- C#高性能大容量SOCKET并发(一):IOCP完成端口例子介绍
- C#高性能大容量SOCKET并发(七):协议字符集
- C#高性能大容量SOCKET并发(五):粘包、分包、解包
- C#高性能大容量SOCKET并发(八):通讯协议
- C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型
- C#高性能大容量SOCKET并发(零):代码结构说明
- C#高性能大容量SOCKET并发(十一):编写上传客户端
- C#高性能大容量SOCKET并发(五):粘包、分包、解包
- C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型
- C#高性能大容量SOCKET并发(五):粘包、分包、解包
- Linux下修改yum的查找方式
- opengl tutorial
- 用 PHP 读取文件的正确方法
- 数学之路-仿生计算-分子生物学基础(1)-细胞合成的分子
- PAT 1013. Battle Over Cities
- C#高性能大容量SOCKET并发(九):断点续传
- 我的第十一课:jQuery - Chaining
- android中动态加载webview,webview加载html数据,并且隐藏滚动条
- SQL Server编写函数获取汉字的拼音码(首字母)
- BZOJ 1503: [NOI2004]郁闷的出纳员
- debian安装国际版QQ中的一些问题记录
- JqGrid 常用使用方法
- 关于“链接规范必须在全局范围内”的错误
- [深度学习]Hinton DBN code 代码分析