原文: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. 《图说VR》——HTC Vive控制器按键事件解耦使用

    本文章由cartzhang编写,转载请注明出处. 全部权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/53915229 作者:car ...

  2. Undefined symbols for architecture i386: "_OBJC_CLASS_$_KKGridView", referenced from:

    Undefined symbols for architecture i386: "_OBJC_CLASS_$_KKGridView", referenced from:

  3. Python应用库大全总结

    学python,想必大家都是从爬虫开始的吧.毕竟网上类似的资源很丰富,开源项目也非常多. python学习网络爬虫主要分3个大的版块:抓取,分析,存储 当我们在浏览器中输入一个url后回车,后台会发生 ...

  4. 【13.77%】【codeforces 734C】Anton and Making Potions

    time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  5. CentOS下Apache的停止和卸载

    昨晚搞到一台全球性价比最高的服务器,折腾一晚上,好不容易把node服务开启了,结果访问不了我的网站!!! 访问我的网站,显示的是一个Apache欢迎页面.我想,是不是像之前那样,80端口没有开放,然后 ...

  6. 从华为产品学到什么是devops

    根据Gartner 2015 I&O Automation 报告,DevOps处于技术发展的最高点,实践受到高度关注,到底devops魔力在哪里? 从devops实践看主要是打破开发人员和运营 ...

  7. POJ 3904(容斥原理)

    Sky Code Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1750   Accepted: 545 Descripti ...

  8. PS 滤镜算法— — 表面模糊

    图像的表面模糊处理,其作用是在保留图像边缘的情况下,对图像的表面进行模糊处理.在对人物皮肤处理上,比高斯模糊更有效.因为高斯模糊在使人物皮肤光洁的同时,也将一些边缘特征如脸部的眉毛.嘴唇等给模糊了,不 ...

  9. ASP.Net请求小周期

    另一篇另篇2 ASP.NET请求处理全过程 一个ASP.NET请求过程中,从浏览器中发出一个Web请求 到 这个请求被响应并显示在浏览器中的过程中究竟会发生哪些不同的事件,当我们进入这个事件之旅时,我 ...

  10. node lesson3

    var express = require('express'); var superagent = require('superagent'); var cheerio = require('che ...