- 浏览: 109009 次
- 性别:
- 来自: 昆明
文章分类
- 全部博客 (151)
- 120D02 (5)
- 直升机 (1)
- 我的技术资料收集 (82)
- 的技术资料收集 (4)
- .NET Solution (2)
- ASP.NET (1)
- Linq to sql (1)
- 数据库技术(MS SQL) (2)
- 架构/设计 (1)
- 敏捷/持续集成 (1)
- C#.NET开发 (1)
- Matlab开发 (1)
- WinForm开发 (1)
- 开源技术 (1)
- jQuery (1)
- 我的博文 (4)
- js (2)
- android (2)
- 9. 读书笔记 (1)
- CSS3 (1)
- HTML5 (1)
- JavaScript (5)
- 移动开发 (2)
- 编程心得 (1)
- Linux操作系统 (1)
- (BI)商业智能 (1)
- IOS (1)
- Windows Phone (2)
- C# API (1)
- JQuery系列 (1)
- TFS (1)
- C# (2)
- ExtJs (1)
- .NET (1)
- Nginx (1)
- WCF学习笔记 (1)
- Computer Graphic (1)
- IT产品 (1)
- 工具分享 (1)
- MySelf (1)
- C#专栏 (1)
- 管理 (1)
- 基于Oracle Logminer数据同步 (1)
- 日常 (1)
- 实用工具 (1)
- 网页设计 (1)
- avalon (1)
- flash (1)
- DDD (1)
- 01 技术Android (1)
- WCF (1)
- selenium (1)
最新评论
-
464410531:
三国杀。。。。。。。。。。。。。。。。。。。。。。。。。。。。 ...
实用的职场宝典:不提拔你,就因为你只想把工作做好
在TCP下进行大文件传输不象小文件那样直接打包个BUFFER发送出去,因为文件比较大所以不可能把文件读到一个BUFFER发送出去.主要有些文件的大小可能是1G,2G或更大,分配这么大的BUFFER对内存来说显然是不现实的事情;针对服务端的设计来说就更需要严紧些,BUFFER大小的限制也是变得很重要.下面介绍使用Beetle简单地实现大文件在TCP的传输应用.
协议制定
既然需要把文件分块来处理,那在TCP传输的过程需要制定一些协议来规范数据有效性,数据协议主要有三个:告诉服务器需要上传文件,文件块上传和返回每个环节处理的结果.
1)上传文件指令
public class Upload:ObjectMessage
{
public string FileMD5
{
get;
set;
}
public string FileName
{
get;
set;
}
public long FileSize
{
get;
set;
}
public override void FromProtocolData(HttpData httpbase)
{
FileName = httpbase[CONSTVALUE.HEADER_NAME];
FileMD5 = httpbase[CONSTVALUE.HEADER_MD5];
FileSize = long.Parse(httpbase[CONSTVALUE.HEADER_FILESIZE]);
}
protected override void OnDisposed()
{
}
protected override void OnToProtocolData(HttpData httpbase)
{
httpbase.Command = CONSTVALUE.COMMAND_UPLOAD;
httpbase[CONSTVALUE.HEADER_MD5] = FileMD5;
httpbase[CONSTVALUE.HEADER_NAME] = FileName;
httpbase[CONSTVALUE.HEADER_FILESIZE] = FileSize.ToString();
}
}
2)上传文件块指令
public class UploadData:ObjectMessage
{
public string FileMD5
{
get;
set;
}
public Beetle.ByteArraySegment Data
{
get;
set;
}
public override void FromProtocolData(HttpData httpbase)
{
FileMD5 = httpbase[CONSTVALUE.HEADER_MD5];
Data = httpbase.Content;
}
protected override void OnDisposed()
{
if (Data != null)
{
FileTransferPackage.BufferPool.Push(Data);
Data = null;
}
}
protected override void OnToProtocolData(HttpData httpbase)
{
httpbase.Command = CONSTVALUE.COMMAND_UPLOAD_DATA;
httpbase[CONSTVALUE.HEADER_MD5] = FileMD5;
httpbase.Content = Data;
}
}
3)返回值指令
public class Result :ObjectMessage
{
public string FileMD5
{
get;
set;
}
public bool Error
{
get;
set;
}
public string ErrorDetail
{
get;
set;
}
public override void FromProtocolData(HttpData httpbase)
{
ErrorDetail = httpbase[CONSTVALUE.HEADER_STATUS_DETAIL];
Error = httpbase[CONSTVALUE.HEADER_STATUS] == CONSTVALUE.VALUE_SUCCESS;
FileMD5 = httpbase[CONSTVALUE.HEADER_MD5];
}
protected override void OnDisposed()
{
}
protected override void OnToProtocolData(HttpData httpbase)
{
httpbase.Command = CONSTVALUE.COMMAND_RESULT;
if (Error)
{
httpbase[CONSTVALUE.HEADER_STATUS] = CONSTVALUE.VALUE_SUCCESS;
}
else
{
httpbase[CONSTVALUE.HEADER_STATUS] = CONSTVALUE.VALUE_ERROR;
}
httpbase[CONSTVALUE.HEADER_STATUS_DETAIL] = ErrorDetail;
httpbase[CONSTVALUE.HEADER_MD5] = FileMD5;
}
}
ObjectMessage是Beetle一个简化HTTP协议的扩展对象,它提供自定义Header和Body等功能.
文件读写器
既然需要处理文件块,那提供一些简单的文件块读取和写入方法是比较重要的.它不仅从设计解决功能的偶合度,还可以方便今后的利用.
1)UploadReader
public class UploadReader : IDisposable
{
public UploadReader(string file)
{
mStream = System.IO.File.OpenRead(file);
StringBuilder sb = new StringBuilder();
MD5 md5Hasher = MD5.Create();
foreach (Byte b in md5Hasher.ComputeHash(mStream))
sb.Append(b.ToString("x2").ToLower());
FileMD5 = sb.ToString();
mStream.Position = 0;
FileSize = mStream.Length;
FileName = System.IO.Path.GetFileName(file);
}
private System.IO.FileStream mStream = null;
public string FileName
{
get;
set;
}
public long LastReadLength
{
get;
set;
}
public long ReadLength
{
get;
set;
}
public long FileSize
{
get;
set;
}
public string FileMD5
{
get;
set;
}
public bool Completed
{
get
{
return mStream != null && ReadLength == mStream.Length;
}
}
public void Close()
{
if (mStream != null)
{
mStream.Close();
mStream.Dispose();
}
}
public void Reset()
{
mStream.Position = 0;
LastReadLength = 0;
ReadLength = 0;
}
public void Read(ByteArraySegment segment)
{
int loads = mStream.Read(segment.Array, 0, FileTransferPackage.BUFFER_SIZE);
segment.SetInfo(0, loads);
ReadLength += loads;
}
public void Dispose()
{
mStream.Dispose();
}
public override string ToString()
{
string value= string.Format("{0}(MD5:{4})\r\n\r\n[{1}/{2}({3}/秒)]",FileName,ReadLength,FileSize,ReadLength-LastReadLength,FileMD5);
if (!Completed)
{
LastReadLength = ReadLength;
}
return value;
}
}
UploadReader的功能主要是把文件流读取到指定大小的Buffer中,并提供方法获取当前的读取情况
2)UploadWriter
public class UploadWriter
{
public UploadWriter(string rootPath, string filename,string fileMD5,long size)
{
mFullName = rootPath + filename;
FileName = filename;
FileMD5 = fileMD5;
Size = size;
}
private string mFullName;
private System.IO.FileStream mStream;
public System.IO.FileStream Stream
{
get
{
if (mStream == null)
{
mStream = System.IO.File.Create(mFullName+".up");
}
return mStream;
}
}
public long WriteLength
{
get;
set;
}
public long LastWriteLength
{
get;
set;
}
public long Size
{
get;
set;
}
public string FileName
{
get;
set;
}
public string FileMD5
{
get;
set;
}
public bool Write(ByteArraySegment segment)
{
Stream.Write(segment.Array, 0, segment.Count);
WriteLength += segment.Count;
Stream.Flush();
if (WriteLength == Size)
{
Stream.Close();
if (System.IO.File.Exists(mFullName))
System.IO.File.Delete(mFullName);
System.IO.File.Move(mFullName + ".up", mFullName);
return true;
}
return false;
}
}
UploadWriter的功能主要是把文件写入到临时文件中,写入完成后再更改相应的名称,为了方便查询同样也提供了一些写入情况信息.
服务端代码
如果有了解过Beetle的服务端制定的话,那服务端的实现是非常简单的,只需要写一个对象承继ServerBase并实现数据接收方法处理即可以,接收的数据会会自动转换成之前定义的消息对象,而服务端内部处理的细节是完全不用关心.
protected override void OnMessageReceive(Beetle.PacketRecieveMessagerArgs e)
{
base.OnMessageReceive(e);
if (e.Message is Protocol.Upload)
{
OnUpload(e.Channel, e.Message as Protocol.Upload);
}
else if (e.Message is Protocol.UploadData)
{
OnUploadData(e.Channel, e.Message as Protocol.UploadData);
}
}
private Protocol.Result GetErrorResult(string detail)
{
Protocol.Result result = new Protocol.Result();
result.Error = true;
result.ErrorDetail = detail;
return result;
}
private void OnUpload(Beetle.TcpChannel channel, Protocol.Upload e)
{
Protocol.Result result;
if (mTask[e.FileMD5] != null)
{
result = GetErrorResult( "该文件正在上传任务中!");
channel.Send(result);
return;
}
UploadWriter writer = new UploadWriter(mRootPath, e.FileName, e.FileMD5, e.FileSize);
lock (mTask)
{
mTask[e.FileMD5] = writer;
}
result = new Protocol.Result();
channel.Send(result);
}
private void OnUploadData(Beetle.TcpChannel channel, Protocol.UploadData e)
{
using (e)
{
Protocol.Result result;
UploadWriter writer = (UploadWriter)mTask[e.FileMD5];
if (writer == null)
{
result = GetErrorResult("上传任务不存在!");
channel.Send(result);
return;
}
if (writer.Write(e.Data))
{
lock (mTask)
{
mTask.Remove(e.FileMD5);
}
}
result = new Protocol.Result();
result.FileMD5 = writer.FileMD5;
channel.Send(result);
}
}
当接收到客户求上传请求后会建立对应MD5的文件写入器,后面文件块的上传写入相关对象即可.
客户端代码
Beetle对于Client的支持也是非常简单方便,只需要定义一个TcpChannel直接发送定义的对象消息并获取服务器端返回的消息即可.
1 private void OnUpload(object state)
2 {
3 Lib.UploadReader reader = (Lib.UploadReader)state;
4 try
5 {
6 IsUpload = true;
7 Lib.Protocol.Upload upload = new Lib.Protocol.Upload();
8 upload.FileMD5 = reader.FileMD5;
9 upload.FileName = reader.FileName;
10 upload.FileSize = reader.FileSize;
11 Lib.Protocol.Result result = mClient.Send<Lib.Protocol.Result>(upload);
12 if (result.Error)
13 {
14 mLastError = result.ErrorDetail;
15 return;
16 }
17 while (!reader.Completed)
18 {
19 mLastError = "文件上传中...";
20 Lib.Protocol.UploadData data = new Lib.Protocol.UploadData();
21 data.Data = Lib.FileTransferPackage.BufferPool.Pop();
22 data.FileMD5 = reader.FileMD5;
23 reader.Read(data.Data);
24 result = mClient.Send<Lib.Protocol.Result>(data);
25 if (result.Error)
26 {
27 mLastError = result.ErrorDetail;
28 return;
29 }
30 }
31 mLastError = "文件上传完成!";
32
33 }
34 catch (Exception e_)
35 {
36 mLastError = e_.Message;
37 }
38 mReader.Reset();
39 IsUpload = false;
40
41 }
整个过程只需要一个方法却可完成,首先把需要上传的文件信息发送到服务器,当服务器确认后不停地把文件块信息输送到服务端即可.
使用测试
下载代码
FileTransfer.Lib.rar (644.64 kb)
发表评论
-
Javascript:猜猜弹出的是啥?为啥? - 幸福框架
2013-06-28 13:33 430原帖地址:http://www.cnblogs.com/hap ... -
C#中WindowsForm常见控件的运用 -- - 李晓峰
2013-06-28 13:27 1747原帖地址:http://www.cnblogs.com/liy ... -
海量数据处理利器之Hash——在线邮件地址过滤 - MyDetail
2013-06-27 12:00 654原帖地址:http://www.cnblo ... -
ASP.NET MVC 4 for Visual Studio 2010 下载地址 - 张鸿伟
2013-06-27 11:48 754原帖地址:http://www.cnblogs.com/wei ... -
【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化 - r01cn
2013-06-26 11:00 919原帖地址:http://www.cnblogs.com/r01 ... -
[珠玑之椟]估算的应用与Little定律 - 五岳
2013-06-26 10:54 639原帖地址:http://www.cnblogs.com/wuy ... -
30行,金额转人民币大写的代码 - 史蒂芬.王
2013-06-26 10:42 1028原帖地址:http://www.cnblogs.com/ste ... -
从银行的钱荒看一个公司的团队建设 产品线过多最终导致最赚钱的项目面临破产 - James Li
2013-06-26 10:36 632原帖地址:http://www.cnblogs.com/Jam ... -
Windows 8 动手实验系列教程 实验6:设置和首选项 - zigzagPath
2013-06-25 13:39 535原帖地址:http://www.cnblogs.com/zig ... -
闲聊可穿戴设备 - shawn.xie
2013-06-25 13:33 616原帖地址:http://www.cnblo ... -
如何使用开源库,吐在VS2013发布之前,顺便介绍下VS2013的新特性"Bootstrap" - 量子计算机
2013-06-25 13:27 869原帖地址:http://www.cnblogs.com/DSh ... -
一步一步将自己的代码转换为观察者模式 - 文酱
2013-06-23 11:36 608原帖地址:http://www.cnblo ... -
iOS内存错误EXC_BAD_ACCESS的解决方法(message sent to deallocated instance) - VicStudio
2013-06-23 11:30 543原帖地址:http://www.cnblogs.com/vic ... -
记录asp.net在IE10下事件丢失排错经过 - Adming
2013-06-23 11:24 712原帖地址:http://www.cnblogs.com/wea ... -
记 FineUI 官方论坛所遭受的一次真实网络攻击!做一个像 ice 有道德的黑客! - 三生石上
2013-06-23 11:18 793原帖地址:http://www.cnblogs.com/san ... -
3、使用Oracle Logminer同步Demo
2013-06-19 10:33 571原帖地址:http://www.cnblogs.com/shi ... -
算法实践——数独的基本解法
2013-06-19 10:27 1450原帖地址:http://www.cnblogs.com/gre ... -
avalon - 初步接触
2013-06-18 10:06 783原帖地址:http://www.cnblogs.com/aar ... -
Nginx学习笔记(一) Nginx架构
2013-06-18 09:59 528原帖地址:http://www.cnblogs.com/cod ... -
证书打印《二》
2013-06-17 10:47 533原帖地址:http://www.cnblogs.com/bin ...
相关推荐
TCP实现的批量大文件传输的C++库,一对多的模型 发送端: 外部调用只需要将文件路径传入,自己去读文件发送,发送端可以指定channel,ip,port,发送时,指定channel推送文件路径即可,挺好用的 接收端: 只需要初始化...
在C#编程语言中,利用Socket API进行TCP通信可以构建高效、稳定的文件传输系统,特别是在处理大文件时,断点续传功能则显得尤为必要。下面,我们将深入探讨如何使用C#的Socket实现TCP大文件传输并支持断点续传。 ...
在TCP文件传输中,通常还会涉及到安全问题。QQ可能会使用SSL/TLS协议对传输的数据进行加密,以保护用户隐私,防止数据被窃取或篡改。 【总结】 基于TCP的文件传输是通过TCP协议的可靠性和顺序性保证文件的安全、...
你可以通过编译和运行这两个项目,来实践TCP文件传输的过程。 在实际应用中,为了提高效率和用户体验,可以考虑使用异步编程模型,例如使用BeginAcceptTcpClient/EndAcceptTcpClient和BeginSend/EndReceive等异步...
在标签中提到了"socket",这意味着实现TCP文件传输是通过套接字编程来完成的。在Python中,我们可以使用socket库来创建客户端和服务器,实现文件的发送和接收。而在Java或其他语言中也有相应的库函数支持。 总的来...
综上所述,"TCP文件传输服务器"项目展示了如何利用TCP协议和VS2015进行网络编程,实现可靠、高效的文件传输服务。通过对文件名和大小的预传输、文件的创建与接收,以及TCP连接的管理,开发者成功地构建了一个基本的...
在IT领域,TCP/IP协议是网络通信的基础...结合断点续传技术,TCP/IP使得文件传输即使在网络不稳定的情况下也能保持高效和完整。在实际应用中,开发者需要理解这些原理,并合理利用它们来构建稳定、高效的文件传输系统。
在这个过程中,程序通常分为发送端和接收端两个部分,通过一系列步骤来实现文件的高效、安全传输。 首先,发送端在传输文件数据前,会将包含文件名和文件长度等元数据的数据包发送给接收端。这样做的目的是让接收端...
### Java 下 TCP 文件传输功能实现 #### 网络协议基础 在理解如何利用 Java 实现基于 TCP 的文件传输之前,我们首先需要了解一些基本的网络协议知识。 **TCP/IP (Transmission Control Protocol/Internet Protocol...
C++ Boost ASIO库是C++开发者用于...总的来说,使用Boost.ASIO实现的异步TCP文件传输是一种高效的方法,尤其适合处理大文件。通过合理的设计和优化,可以实现接近10MB/s的传输速度,同时保证了系统的响应性和稳定性。
总的来说,这个工具利用TCP的可靠性和流控特性,配合合理的文件分块和传输策略,确保了大文件在复杂网络环境下的安全、高效传输。如果你对网络编程或大文件传输有兴趣,研究这个开源项目将是一个很好的学习机会。
在本文中,我们将深入探讨如何使用C#进行TCP文件传输,特别关注WinForm应用程序的实现。TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,广泛应用于网络编程,包括文件...
下面将详细讨论如何在局域网环境中,利用TCP/IP协议实现大文件的高效、稳定传输。 首先,TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输协议。它通过三次握手建立连接,确保数据传输前双方已...
在Linux系统中,我们可以使用各种编程语言(如C、Python、Java等)结合socket编程来实现TCP文件传输。首先,我们需要创建一个服务器端程序,它监听特定的端口,等待客户端连接。当客户端连接上服务器后,服务器端...
本项目“基于TCP/UDP的文件传输”着重探讨了如何利用这两种协议进行文件的可靠传输,特别是在实现UDP的可靠性方面。 TCP是一种面向连接的协议,它提供了可靠的、基于字节流的数据传输服务。TCP通过三次握手建立连接...
在这个项目中,"基于VC++的TCP文件传输系统",我们关注的重点是如何利用Microsoft Visual C++(VC++)这一强大的开发工具,结合C++语言,实现基于传输控制协议(TCP)的文件传输功能。下面我们将深入探讨这个主题...
TCP文件批量传输是指通过TCP协议来实现大量文件的高效、可靠传输。在这个过程中,我们可以从以下几个方面来理解相关知识点: 1. **TCP协议基础**:TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。它...
TCP(Transmission ...总的来说,这个项目提供了学习TCP文件传输和P2P Socket编程的实例,有助于深入理解网络通信的底层原理和实践应用。通过阅读和分析代码,可以了解到如何在C++中实现可靠、高效的文件传输服务。
TCP以其可靠性著称,能够确保数据的完整性和顺序性,是实现大文件传输的重要技术。本篇将深入探讨TCP在处理大文件传输时的关键概念、机制以及与socket编程的结合。 首先,TCP提供面向连接的服务,这意味着在数据...
在这个项目中,我们将关注使用VC++在Windows环境下实现TCP文件传输的功能。 TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。它通过三次握手建立连接,确保数据传输前双方已准备好;通过确认机制、重传...