基于TCP网络通信的自动升级程序源码分析-服务器发送文件
2015-02-02 14:08
846 查看
基于TCP网络通信的自动升级程序源码分析-服务器发送文件
服务器发送文件using System; using System.Collections.Generic; using System.Text; using NetworkCommsDotNet; using System.ComponentModel; using System.IO; using NetworkCommsDotNet.Connections; using NetworkCommsDotNet.Tools; using NetworkCommsDotNet.Connections.TCP; using System.Threading; using Upgrade.Business; using NetworkCommsDotNet.DPSBase; namespace AppServer { public class SendFile { //传输过程 public event EventHandler<FTProgressEventArgs> FileTransProgress; //传输完成 public event EventHandler<FTCompleteEventArgs> FileTransCompleted; //传输中断 public event EventHandler<FTDisruptEventArgs> FileTransDisruptted; //取消文件的发送 private volatile bool canceled = false; //文件传送失败的原因 private FileTransFailReason fileTransDisrupttedType = FileTransFailReason.Error; public string FilePath { get; private set; } /// <summary> /// The connectionInfo corresponding with the source /// 连接信息 /// </summary> public ConnectionInfo SourceInfo { get; private set; } /// <summary> /// 收发参数 /// </summary> private SendReceiveOptions sendFileOptions = null; private Connection connection; public Connection Connection { get { return connection;} set { connection = value;} } //文件发送相关参数 private FileTransOptions fileTransOptions; public FileTransOptions FileTransOptions { get { return fileTransOptions; } set { fileTransOptions = value; } } //文件ID 用于管理文件 和文件的发送 取消发送相关 private string fileID; public string FileID { get { return fileID; } set { fileID = value; } } //文件传输后存储的路径 客户端传过来的路径 再传回去 private string destFilePath; public string DestFilepath { get { return destFilePath; } set { destFilePath = value; } } /// <summary> /// The total size in bytes of the file /// 文件的字节大小 /// </summary> public long SizeBytes { get; private set; } /// <summary> /// The total number of bytes received so far /// 目前收到的文件的带下 /// </summary> public long SentBytes { get; private set; } /// <summary> /// Getter which returns the completion of this file, between 0 and 1 ///已经完成的百分比 /// </summary> public double CompletedPercent { get { return (double)SentBytes / SizeBytes; } //This set is required for the application to work set { throw new Exception("An attempt to modify read-only value."); } } /// <summary> /// A formatted string of the SourceInfo /// 源信息 /// </summary> public string SourceInfoStr { get { return "[" + SourceInfo.RemoteEndPoint.ToString() + "]"; } } /// <summary> /// Returns true if the completed percent equals 1 /// 是否完成 /// </summary> public bool IsCompleted { get { return SentBytes == SizeBytes; } } /// <summary> /// Private object used to ensure thread safety /// </summary> object SyncRoot = new object(); //构造函数 public SendFile(string fileID, string filePath, string destFilePath, Connection connection, SendReceiveOptions sendReceiveOptions, FileTransOptions fileTransOptions) { //文件ID this.fileID = fileID; this.FilePath = filePath; this.destFilePath = destFilePath; this.connection = connection; this.fileTransOptions = fileTransOptions; this.sendFileOptions = new SendReceiveOptions(DPSManager.GetDataSerializer<ProtobufSerializer>(), null, null); this.sendFileOptions.ReceiveHandlePriority = NetworkCommsDotNet.Tools.QueueItemPriority.Lowest; } //异步方法发送文件 public void NowSendFile() { new Action(this.StartSendFile).BeginInvoke(null, null); } //发送文件 public void StartSendFile() { FileStream stream = null; try { //Create a fileStream from the selected file //根据选择的文件创建一个文件流 stream = new FileStream(this.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read); //包装成线程安全的数据流 StreamTools.ThreadSafeStream safeStream = new StreamTools.ThreadSafeStream(stream); //Get the filename without the associated path information //获取不包含路径信息的文件名 string shortFileName = System.IO.Path.GetFileName(FilePath); //根据参数中设定的值来角色发送的数据包的大小 long sendChunkSizeBytes = fileTransOptions.PackageSize; this.SizeBytes = stream.Length; long totalBytesSent = 0; do { // 此次发送的字节数 // 如果剩余的字节数小于 (我们前面定义的每次发送的字节数) 则按照剩余字节数发送 否则 按照
(我们前面定义的每次发送的字节数)发送
long bytesToSend = (totalBytesSent + sendChunkSizeBytes < stream.Length ? sendChunkSizeBytes : stream.Length - totalBytesSent); StreamTools.StreamSendWrapper streamWrapper = new StreamTools.StreamSendWrapper(safeStream, totalBytesSent, bytesToSend); //我们希望记录包的顺序号 用于在接收端对应数据文件和数据接收文件 long packetSequenceNumber; //发送数据文件 connection.SendObject("PartialFileData", streamWrapper, sendFileOptions, out packetSequenceNumber); //发送数据文件相对应的信息 (把包的顺序号记录在 SendInfo类中) connection.SendObject("PartialFileDataInfo", new SendInfo(fileID, shortFileName, destFilePath, stream.Length, totalBytesSent, packetSequenceNumber), sendFileOptions); totalBytesSent += bytesToSend; //更新已经发送的字节的属性 SentBytes += bytesToSend; FileTransProgress.Raise(this, new FTProgressEventArgs(FileID, SizeBytes, totalBytesSent)); //Thread.Sleep(30); if (!((this.fileTransOptions.SleepSpan <= 0) || this.canceled)) { Thread.Sleep(this.fileTransOptions.SleepSpan); } } while ((totalBytesSent < stream.Length) && !this.canceled); if (!this.canceled) { FileTransCompleted.Raise(this, new FTCompleteEventArgs(fileID)); } else { //应该发送一个消息给对方,告诉对方文件中断☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ FileTransDisruptted.Raise(this, new FTDisruptEventArgs(FileID, FileTransFailReason.Error)); } } catch (CommunicationException ex) { //If there is a communication exception then we just write a connection //closed message to the log window //AddLineToLog("Failed to complete send as connection was closed."); LogTools.LogException(ex, "SendFile.StartSendFile"); FileTransDisruptted.Raise(this, new FTDisruptEventArgs(FileID, FileTransFailReason.Error)); } catch (Exception ex) { LogTools.LogException(ex, "SendFile.StartSendFile"); FileTransDisruptted.Raise(this, new FTDisruptEventArgs(FileID, FileTransFailReason.Error)); } finally { if (stream != null) { stream.Close(); } } } //取消文件的发送 public void Cancel(FileTransFailReason disrupttedType) { try { this.canceled = true; this.fileTransDisrupttedType = disrupttedType; FileTransDisruptted.Raise(this, new FTDisruptEventArgs(FileID, FileTransFailReason.Error)); } catch (Exception ex) { LogTools.LogException(ex, "SendFile.Cancel"); } } } }
www.networkcomms.cn
www.cnblogs.com/networkcomms 编辑
【开源下载】基于TCP网络通信的自动升级程序c#源码
[源码下载]Demo2.模拟简单登陆-效果图
基于networkcomms2.3.1
[源码下载]Demo1
客户端从服务器获取信息(基于networkcomms2.3.1)
相关文章:基于TCP网络通信的自动升级程序源码分析--生成升级文件相关的配置文件
基于TCP网络通信的自动升级程序源码分析-客户端连接服务器
基于TCP网络通信的自动升级程序源码分析-客户端请求服务器上的升级信息
基于TCP网络通信的自动升级程序源码分析-启动升级文件下载程序
基于TCP网络通信的自动升级程序源码分析-服务器发送文件
基于TCP网络通信的自动升级程序源码分析-客户端接收文件
相关文章推荐
- 基于TCP网络通信的自动升级程序源码分析-服务器发送文件
- 基于TCP网络通信的自动升级程序源码分析--生成升级文件相关的配置文件
- 基于TCP网络通信的自动升级程序源码分析-客户端连接服务器
- 基于TCP网络通信的自动升级程序源码分析-客户端请求服务器上的升级信息
- 基于TCP网络通信的自动升级程序源码分析-客户端连接服务器
- 基于TCP网络通信的自动升级程序源码分析-客户端请求服务器上的升级信息
- 基于TCP网络通信的自动升级程序源码分析-客户端连接服务器
- 基于TCP网络通信的自动升级程序源码分析-启动升级文件下载程序
- 基于TCP网络通信的自动升级程序源码分析-客户端接收文件
- 基于TCP网络通信的自动升级程序源码分析-启动升级文件下载程序
- 基于TCP网络通信的自动升级程序源码分析--生成升级文件相关的配置文件
- 基于TCP网络通信的自动升级程序源码分析-客户端接收文件
- 基于TCP网络通信的自动升级程序源码分析-客户端接收文件
- 基于TCP网络通信的自动升级程序源码分析-启动升级文件下载程序
- 【开源下载】基于TCP网络通信的自动升级程序c#源码
- 【开源下载】基于TCP网络通信的自动升级程序c#源码
- [c#源码分享]客户端程序通过TCP通信传送"小文件"到服务器
- 基于Tcp通信的聊天程序微风IM(c#开源) -技术分析(二) 消息转发
- Qt5 基于TCP传输的发送/接收文件服务器(支持多客户端)
- 【转】【开源下载】基于TCP网络通信的即时聊天系统(IM系统)(c#源码)