原文:C#高性能大容量SOCKET并发(九):断点续传

上传断点续传

断点续传主要是用在上传或下载文件,一般做法是开始上传的时候,服务器返回上次已经上传的大小,如果上传完成,则返回-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并发(九):断点续传的更多相关文章

  1. C#高性能大容量SOCKET并发(转)

    C#高性能大容量SOCKET并发(零):代码结构说明 C#高性能大容量SOCKET并发(一):IOCP完成端口例子介绍 C#高性能大容量SOCKET并发(二):SocketAsyncEventArgs ...

  2. C#高性能大容量SOCKET并发(十一):编写上传客户端

    原文:C#高性能大容量SOCKET并发(十一):编写上传客户端 客户端封装整体框架 客户端编程基于阻塞同步模式,只有数据正常发送或接收才返回,如果发生错误则抛出异常,基于TcpClient进行封装,主 ...

  3. C#高性能大容量SOCKET并发(零):代码结构说明

    原文:C#高性能大容量SOCKET并发(零):代码结构说明 C#版完成端口具有以下特点: 连接在线管理(提供在线连接维护,连接会话管理,数据接收,连接断开等相关事件跟踪): 发送数据智能合并(组件会根 ...

  4. C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型

    原文:C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型 线程模型 SocketAsyncEventArgs编程模式不支持设置同时工作线程个数,使用的NET的IO ...

  5. C#高性能大容量SOCKET并发(七):协议字符集

    原文:C#高性能大容量SOCKET并发(七):协议字符集 UTF-8 UTF-8是UNICODE的一种变长字符编码又称万国码,由Ken Thompson于1992年创建.现在已经标准化为RFC 362 ...

  6. C#高性能大容量SOCKET并发(六):超时Socket断开(守护线程)和心跳包

    原文:C#高性能大容量SOCKET并发(六):超时Socket断开(守护线程)和心跳包 守护线程 在服务端版Socket编程需要处理长时间没有发送数据的Socket,需要在超时多长时间后断开连接,我们 ...

  7. C#高性能大容量SOCKET并发(五):粘包、分包、解包

    原文:C#高性能大容量SOCKET并发(五):粘包.分包.解包 粘包 使用TCP长连接就会引入粘包的问题,粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一 ...

  8. C#高性能大容量SOCKET并发(三):接收、发送

    原文:C#高性能大容量SOCKET并发(三):接收.发送 异步数据接收有可能收到的数据不是一个完整包,或者接收到的数据超过一个包的大小,因此我们需要把接收的数据进行缓存.异步发送我们也需要把每个发送的 ...

  9. C#高性能大容量SOCKET并发(四):缓存设计

    原文:C#高性能大容量SOCKET并发(四):缓存设计 在编写服务端大并发的应用程序,需要非常注意缓存设计,缓存的设计是一个折衷的结果,需要通过并发测试反复验证.有很多服务程序是在启动时申请足够的内存 ...

随机推荐

  1. php课程 6-21 HTML标签相关函数

    php课程 6-21 HTML标签相关函数 一.总结 一句话总结:1.存入数据库的html标签代码:$info=addslashes(htmlspecialchars($_POST['info'])) ...

  2. 【bzoj2809】派遣 (左偏树)

    传送门 题目分析 每个节点都是一颗(大根堆)左偏树,先按bfs序存入数组,然后倒着从底层开始:如果当前节点的子树sum > m 那么就把根节点删去,然后统计更新答案,并将这棵树和父节点合并. c ...

  3. xaml 添加 region

    原文:xaml 添加 region 本文告诉大家如何在 xaml 添加 region 在 VisualStudio 2015 和 VisualStudio 2017 微软支持在 xmal 使用 reg ...

  4. Windows下MinGW跨平台编译和使用log4cpp

    Log4cpp 是C++开源日志库,为 C++ 应用程序开发中提供了日志的追踪和调试功能,基于 LGPL 开源协议,移植自 java 的日志项目 log4j, 并在 api 上保持了一致性. 1. 环 ...

  5. Android中的事件处理研究

    处理用户界面事件Handling UI Events 在Android上,不止一个途径来侦听用户和应用程序之间交互的事件.对于用户界面里的事件,侦听方法就是从与用户交互的特定视图对象截获这些事件.视图 ...

  6. sqlserver中获取最后一个字符所在的位置

    CHARINDEX('字符',reverse(字段名称)) 这个意思就是将字段进行反转,就是从后往前取,这样就能够获取一个字符最后所在的位置

  7. 各个版本 Windows 10 系统中自带的 .NET Framework 版本

    原文各个版本 Windows 10 系统中自带的 .NET Framework 版本 Windows 名称 Windows 版本 自带的 .NET Framework 版本 Windows 10 Oc ...

  8. uwp - 禁用屏幕翻转/禁用屏幕旋转/禁用横屏模式

    原文:uwp - 禁用屏幕翻转/禁用屏幕旋转/禁用横屏模式 解决方案目录 > Package.appxmanifest 双击打开,把支持的旋转:纵向勾上,只勾这一个其他不勾,就可以了.同理,想让 ...

  9. android4.4系统解决“ERRORcouldn't find native method”方法

    android4.4系统解决"ERRORcouldn't find native method"方法 今天笔者在移植一个tv模块从android4.2到android4.4系统的设 ...

  10. C#中的DataGridView

    关键字:C# DataGridView作者:peterzb来源:http://www.cnblogs.com/peterzb 1.DataGridView实现课程表 testcontrol.rar 2 ...