博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
supersocket实现上传文件
阅读量:4364 次
发布时间:2019-06-07

本文共 17037 字,大约阅读时间需要 56 分钟。

0.先上章效果图吧;

1.目录结构:

2.上传客户端类库介绍:

   ITransferEngine:

 

public interface ITransferEngine    {        ///         /// 该事件接口暴露了所有正在上传的文件(夹)的实时状态。        ///         IFileUploadingEvents FileUploadingEvents { get; }        void BeginUpLoad(string fileName, string saveName);        void BeginUpLoad(string fileName, string saveName, ref string fileId, ref string AddId);    }    public interface IFileUploadingEvents    {        event BTransferEventHandler
FileExist; event TransferEventHandler
TransferComplete; event TransferEventHandler
TransferError; event TransferEventHandler
TransferStep; }

TransferEngine:

internal class TransferEngine : ITransferEngine    {        private FileUploadingEvents _FileUploadingEvents;        public IFileUploadingEvents FileUploadingEvents { get { return _FileUploadingEvents; } }        public TransferEngine()        {            _FileUploadingEvents = new FileUploadingEvents();        }        public void BeginUpLoad(string fileName, string saveName)        {            EndPoint endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2020);            UpLoadEngine engine = new UpLoadEngine(_FileUploadingEvents);            engine.Init(endpoint, fileName, Path.GetFileName(fileName));            engine.BeginUpLoad();        }        public void BeginUpLoad(string fileName, string saveName, ref string fileId, ref string AddId)        {            EndPoint endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2020);            UpLoadEngine engine = new UpLoadEngine(_FileUploadingEvents);            engine.Init(endpoint, fileName, saveName);            engine.BeginUpLoad(ref fileId, ref AddId);        }    }

上传的相关事件:

public delegate void TransferEventHandler
(TEventArgs e); public delegate bool BTransferEventHandler
(TEventArgs e); public class TransferStepEventArgs : EventArgs { public TransferStepEventArgs(long _TotalLen, long _TransferLen, int _CurrentPacket) { this.TotalLen = _TotalLen; this.TransferLen = _TransferLen; this.CurrentPacket = _CurrentPacket; } public int CurrentPacket { get; set; } public long TotalLen { get; set; } public long TransferLen { get; set; } } public class TransferErrorEventArgs : EventArgs { public TransferErrorEventArgs(System.Exception exception) { this.Exception = exception; } public System.Exception Exception { get; private set; } }
internal class FileUploadingEvents : IFileUploadingEvents    {        internal BTransferEventHandler
OnFileExist; internal TransferEventHandler
OnTransferComplete; internal TransferEventHandler
OnTransferError; internal TransferEventHandler
OnTransferStep; public event BTransferEventHandler
FileExist { add { OnFileExist = (BTransferEventHandler
)System.Delegate.Combine(OnFileExist, value); } remove { OnFileExist = (BTransferEventHandler
)System.Delegate.Remove(OnFileExist, value); } } public event TransferEventHandler
TransferComplete { add { OnTransferComplete = (TransferEventHandler
)System.Delegate.Combine(OnTransferComplete, value); } remove { OnTransferComplete = (TransferEventHandler
)System.Delegate.Remove(OnTransferComplete, value); } } public event TransferEventHandler
TransferError { add { OnTransferError = (TransferEventHandler
)System.Delegate.Combine(OnTransferError, value); } remove { OnTransferError = (TransferEventHandler
)System.Delegate.Remove(OnTransferError, value); } } public event TransferEventHandler
TransferStep { add { OnTransferStep = (TransferEventHandler
)System.Delegate.Combine(OnTransferStep, value); } remove { OnTransferStep = (TransferEventHandler
)System.Delegate.Remove(OnTransferStep, value); } } }

UpLoadEngine:

internal class UpLoadEngine : IDisposable    {        FileUploadingEvents FileUploadingEvents;        protected IClientCommandReader
CommandReader { get; private set; } private string _fileName; public string _saveName; private Dictionary
> m_CommandDict = new Dictionary
>(StringComparer.OrdinalIgnoreCase); private FileStream m_fileStream; private int PacketSize = 1024 * 30; private byte[] readBuffer; private long TransferedLength = 0L; internal int TransferStatus = 0; //0:初始化状态,1:CheckExist,3,OnUpLoad,开始上传,4,OnDoData,数据传输中,5,数据传输完成,6,已结束的标志 private long TransferTotalLength = 0L; internal TcpClientSession Client; internal AutoResetEvent m_OpenedEvent = new AutoResetEvent(false); internal AutoResetEvent m_EndEvent = new AutoResetEvent(false); public UpLoadEngine(FileUploadingEvents _FileUploadingEvents) { this.FileUploadingEvents = _FileUploadingEvents; } public void BeginUpLoad() { try { if (this.TransferStatus != 0) { throw new Exception("状态错误"); } this.Client.Connect(); if (!this.m_OpenedEvent.WaitOne(5000)) { throw new Exception("连接失败"); } this.SendMessage(UpLoadOP.CheckExist, this._saveName); } catch (Exception exception) { this.OnTransferError(new TransferErrorEventArgs(exception)); } } internal void BeginUpLoad(ref string fileId, ref string AddId) { BeginUpLoad(); fileId = string.Empty; AddId = string.Empty; } private void client_Closed(object sender, EventArgs e) { this.TransferStatus = 6; } private void client_Connected(object sender, EventArgs e) { this.m_OpenedEvent.Set(); } private void client_DataReceived(object sender, DataEventArgs e) { this.m_OnDataReceived(e.Data, e.Offset, e.Length); } private void client_Error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e) { } public void Dispose() { this._fileName = string.Empty; this._saveName = string.Empty; if (this.m_fileStream != null) { this.m_fileStream.Close(); this.m_fileStream = null; } TcpClientSession client = this.Client; if (client != null) { client.Error -= new EventHandler
(this.client_Error); client.DataReceived -= new EventHandler
(this.client_DataReceived); client.Connected -= new EventHandler(this.client_Connected); client.Closed -= new EventHandler(this.client_Closed); if (client.IsConnected) { client.Close(); } this.Client = null; } //this.TransferStatus = 0; this.TransferedLength = 0L; this.TransferTotalLength = 0L; this.readBuffer = null; this.CommandReader = null; this.m_CommandDict.Clear(); this.m_OpenedEvent.Reset(); this.m_EndEvent.Reset(); } internal void DoData() { this.TransferStatus = 4; while (this.TransferedLength < this.TransferTotalLength) { if (this.TransferStatus == 6) { if (this.Client != null && !this.Client.IsConnected) { this.OnTransferError(new TransferErrorEventArgs(new Exception("服务端关闭"))); return; } else { this.DoEnd(); return; } } int length = this.m_fileStream.Read(this.readBuffer, 0, this.PacketSize); this.SendData(UpLoadOP.DoData, this.readBuffer, 0, length); this.TransferedLength += length; this.OnTransferStep(this.TransferTotalLength, this.TransferedLength, length); } this.TransferStatus = 5; this.SendData(UpLoadOP.DoEnd, new byte[] { 1 }, 0, 1); DoEnd(); } internal void DoEnd() { this.TransferStatus = 6; this.Dispose(); if (this.FileUploadingEvents.OnTransferComplete != null) { this.FileUploadingEvents.OnTransferComplete(new EventArgs()); } } //客户端自己触发结束事件 //internal void OnDoEnd() //{ // DoEnd(); //} internal void DoUpLoad() { this.m_fileStream = new FileStream(this._fileName, FileMode.Open, FileAccess.Read); this.TransferTotalLength = this.m_fileStream.Length; UpLoadInfo t = new UpLoadInfo(this._fileName, this.m_fileStream.Length, _SaveName: this._saveName); byte[] data = SerializeHelp.Serialize
(t); this.SendData(UpLoadOP.DoUpLoad, data, 0, data.Length); } private void ExecuteCommand(TransferCommandInfo commandInfo) { ICommand
command; if (this.m_CommandDict.TryGetValue(commandInfo.Key, out command)) { command.ExecuteCommand(this, commandInfo); } } public void Init(EndPoint endpoint, string fileName, string saveName) { string str = ConfigurationManager.AppSettings["PacketSize"]; if (!string.IsNullOrWhiteSpace(str)) { this.PacketSize = Convert.ToInt32(str); } this.readBuffer = new byte[this.PacketSize]; this._fileName = fileName; this._saveName = saveName; UpLoadCommandBase[] baseArray = new UpLoadCommandBase[] { new CheckExist(), new TransferClientLib.UpLoad.Command.DoData(), new TransferClientLib.UpLoad.Command.DoEnd() }; foreach (UpLoadCommandBase base2 in baseArray) { this.m_CommandDict.Add(base2.Name, base2); } TcpClientSession session = new AsyncTcpSession(endpoint); session.Error += new EventHandler
(this.client_Error); session.DataReceived += new EventHandler
(this.client_DataReceived); session.Connected += new EventHandler(this.client_Connected); session.Closed += new EventHandler(this.client_Closed); this.Client = session; this.CommandReader = new UpLoadReader(this); } private void m_OnDataReceived(byte[] data, int offset, int length) { while (true) { if (this.CommandReader == null) return; int num; TransferCommandInfo commandInfo = this.CommandReader.GetCommandInfo(data, offset, length, out num); if (this.CommandReader.NextCommandReader != null) { this.CommandReader = this.CommandReader.NextCommandReader; } if (commandInfo != null) { this.ExecuteCommand(commandInfo); } if (num <= 0) { return; } offset = (offset + length) - num; length = num; } } internal bool OnFileExist() { if (this.FileUploadingEvents.OnFileExist != null) { this.FileUploadingEvents.OnFileExist(new EventArgs()); } this.OnTransferError(new TransferErrorEventArgs(new Exception("存在相同文件"))); return false; } internal void OnTransferError(TransferErrorEventArgs e) { if (this.FileUploadingEvents.OnTransferError != null) { this.FileUploadingEvents.OnTransferError(e); } this.Dispose(); } internal void OnTransferStep(long _TotalLen, long _TransferLen, int _CurrentPacket) { if (this.FileUploadingEvents.OnTransferStep != null) { this.FileUploadingEvents.OnTransferStep(new TransferStepEventArgs(_TotalLen, _TransferLen, _CurrentPacket)); } } internal void SendData(UpLoadOP opCode, byte[] data, int offset, int length) { byte[] senddata = new byte[length + 5]; senddata[0] = 0; senddata[1] = (byte)((int)opCode / 256); senddata[2] = (byte)((int)opCode % 256); senddata[3] = (byte)(length / 256); senddata[4] = (byte)(length % 256); Buffer.BlockCopy(data, offset, senddata, 5, length); this.Client.Send(senddata, 0, senddata.Length); } internal void SendMessage(UpLoadOP opCode, string msg) { byte[] bytes = Encoding.UTF8.GetBytes(msg); this.SendData(opCode, bytes, 0, bytes.Length); } }

 3.服务端

UpLoadEngine,应该命名叫UpLoadServerEngine,跟客户端有个区分

public class UpLoadEngine : IDisposable    {        private AutoResetEvent m_EndEvent = new AutoResetEvent(false);        private FileStream m_fileStream;        private int TransferStatus = 0;        //0:初始化状态,1:CheckFile,3,OnUpLoad,开始上传,4,OnDoData,数据接受中,5,数据接受完成,6,已结束的标志        public long TransferedLength = 0L;        private TransferServerLib.TransferSession TransferSession;        public TransferCommon.UpLoadInfo UpLoadInfo;        Thread thread;        public delegate void TransferStepEventHandler(TransferStepEventArgs e);        public event TransferStepEventHandler TransferStep;        public delegate void TransferCompleteEventHandler(EventArgs e);        public event TransferCompleteEventHandler TransferComplete;        public delegate void StartTransferEventHandler(StartTransferEventArgs e);        public event StartTransferEventHandler StartTransfer;        public UpLoadEngine(TransferServerLib.TransferSession _TransferSession)        {            this.TransferStatus = 0;            this.TransferSession = _TransferSession;        }        public void Dispose()        {            if (this.m_fileStream != null)            {                this.m_fileStream.Close();                this.m_fileStream = null;            }            if (this.TransferSession != null)            {                this.TransferSession.Close();                this.TransferSession = null;            }            if (thread != null)            {                if (thread.IsAlive)                    thread.Abort();                thread = null;            }            this.UpLoadInfo = null;            this.TransferedLength = 0L;        }        internal void OnCheckFile(UpLoadOP opCode, bool IsFileExist)        {            this.TransferStatus = 1;            string s = IsFileExist ? "1" : "0";            byte[] bytes = Encoding.UTF8.GetBytes(s);            this.SendData(opCode, bytes, 0, bytes.Length);        }        public void OnDoData(byte[] data, int offset, int count)        {            this.TransferStatus = 4;            this.m_fileStream.Write(data, offset, count);            this.TransferedLength += count;            this.OnTransferStep(this.UpLoadInfo.TransferLength, TransferedLength, count);            if (this.TransferedLength >= this.UpLoadInfo.TransferLength)            {                this.TransferStatus = 5;                thread = new Thread(new ThreadStart(() =>                {                    if (!this.m_EndEvent.WaitOne(5000))                    {                        if (this.TransferStatus < 6)                        {                            DoEnd();                        }                    }                }));                thread.IsBackground = true;                thread.Start();            }        }        internal void OnTransferStep(long _TotalLen, long _TransferLen, int _CurrentPacket)        {            if (this.TransferStep != null)            {                this.TransferStep(new TransferStepEventArgs(_TotalLen, _TransferLen, _CurrentPacket));            }        }        public void DoEnd()        {            this.TransferSession.Close();            this.Dispose();            this.TransferStatus = 6;            if (TransferComplete != null)                TransferComplete(new EventArgs());        }        public void OnDoEnd()        {            DoEnd();        }        internal void OnUpLoad(TransferCommon.UpLoadInfo uploadInfo)        {            this.TransferStatus = 3;            this.UpLoadInfo = uploadInfo;            if (StartTransfer != null)            {                StartTransfer(new StartTransferEventArgs(uploadInfo));            }            string fullPath = Path.GetFullPath(uploadInfo.SaveName);            string dirPath = Path.GetDirectoryName(fullPath);            if (!Directory.Exists(dirPath))            {                Directory.CreateDirectory(dirPath);            }            this.m_fileStream = new FileStream(fullPath, FileMode.OpenOrCreate, FileAccess.Write);            this.m_fileStream.SetLength(uploadInfo.FileSize);            this.SendData(UpLoadOP.DoData, new byte[] { 1 }, 0, 1);        }        internal void SendData(UpLoadOP opCode, byte[] data, int offset, int length)        {            byte[] dst = new byte[length + 4];            dst[0] = (byte)((int)opCode / 256);            dst[1] = (byte)((int)opCode % 256);            dst[2] = (byte)(data.Length / 256);            dst[3] = (byte)(data.Length % 256);            Buffer.BlockCopy(data, offset, dst, 4, length);            this.TransferSession.Send(dst, 0, dst.Length);        }    }

程序还没写好,还要更新,请多多指点

源码:

git os china ,为啥不用github,因为速度没有oschina快。

转载于:https://www.cnblogs.com/dishiyicijinqiu/p/4606880.html

你可能感兴趣的文章
最佳实践 | OceanBase事务引擎的技术创新
查看>>
unity中开启和关闭协同程序
查看>>
hdu_2089_不要62(数位DP)
查看>>
red and black(BFS)
查看>>
887. Super Egg Drop
查看>>
Properties类加载属性文件
查看>>
堆和栈&值类型和引用类型&拆箱和装箱
查看>>
HTML5外包团队:HTML5 Canvas使用教程
查看>>
内核调试日志打印宏
查看>>
C语言中格式化输出,四舍五入类型问题
查看>>
ListView
查看>>
WPF浏览器应用程序与JS的互调用(不用WebBrowser)
查看>>
bzoj2820: YY的GCD
查看>>
链表后续完善(一)
查看>>
Netsharp快速入门(之13) 销售管理(单据流转 销售订单生成发货单)
查看>>
郑州大学2018新生训练赛第十场题解
查看>>
相关子查询和嵌套子查询
查看>>
Oracle分析函数入门
查看>>
线段拟合(带拉格朗日乘子,HGL)
查看>>
oracle数据库服务介绍
查看>>