• supersocket实现上传文件


    0.先上章效果图吧;

    1.目录结构:

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

       ITransferEngine:

        public interface ITransferEngine
        {
            /// <summary>
            /// 该事件接口暴露了所有正在上传的文件(夹)的实时状态。
            /// </summary>
            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<EventArgs> FileExist;
            event TransferEventHandler<EventArgs> TransferComplete;
            event TransferEventHandler<TransferErrorEventArgs> TransferError;
            event TransferEventHandler<TransferStepEventArgs> 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>(TEventArgs e);
        public delegate bool BTransferEventHandler<TEventArgs>(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<EventArgs> OnFileExist;
    
            internal TransferEventHandler<EventArgs> OnTransferComplete;
    
            internal TransferEventHandler<TransferErrorEventArgs> OnTransferError;
    
            internal TransferEventHandler<TransferStepEventArgs> OnTransferStep;
            public event BTransferEventHandler<EventArgs> FileExist
            {
                add { OnFileExist = (BTransferEventHandler<EventArgs>)System.Delegate.Combine(OnFileExist, value); }
                remove { OnFileExist = (BTransferEventHandler<EventArgs>)System.Delegate.Remove(OnFileExist, value); }
            }
            public event TransferEventHandler<EventArgs> TransferComplete
            {
                add { OnTransferComplete = (TransferEventHandler<EventArgs>)System.Delegate.Combine(OnTransferComplete, value); }
                remove { OnTransferComplete = (TransferEventHandler<EventArgs>)System.Delegate.Remove(OnTransferComplete, value); }
            }
    
            public event TransferEventHandler<TransferErrorEventArgs> TransferError
            {
                add { OnTransferError = (TransferEventHandler<TransferErrorEventArgs>)System.Delegate.Combine(OnTransferError, value); }
                remove { OnTransferError = (TransferEventHandler<TransferErrorEventArgs>)System.Delegate.Remove(OnTransferError, value); }
            }
    
            public event TransferEventHandler<TransferStepEventArgs> TransferStep
            {
                add { OnTransferStep = (TransferEventHandler<TransferStepEventArgs>)System.Delegate.Combine(OnTransferStep, value); }
                remove { OnTransferStep = (TransferEventHandler<TransferStepEventArgs>)System.Delegate.Remove(OnTransferStep, value); }
            }
        }

    UpLoadEngine:

    internal class UpLoadEngine : IDisposable
        {
            FileUploadingEvents FileUploadingEvents;
            protected IClientCommandReader<TransferCommandInfo> CommandReader { get; private set; }
            private string _fileName;
            public string _saveName;
            private Dictionary<string, ICommand<UpLoadEngine, TransferCommandInfo>> m_CommandDict = new Dictionary<string, ICommand<UpLoadEngine, TransferCommandInfo>>(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<SuperSocket.ClientEngine.ErrorEventArgs>(this.client_Error);
                    client.DataReceived -= new EventHandler<DataEventArgs>(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<UpLoadInfo>(t);
                this.SendData(UpLoadOP.DoUpLoad, data, 0, data.Length);
            }
    
            private void ExecuteCommand(TransferCommandInfo commandInfo)
            {
                ICommand<UpLoadEngine, TransferCommandInfo> 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<SuperSocket.ClientEngine.ErrorEventArgs>(this.client_Error);
                session.DataReceived += new EventHandler<DataEventArgs>(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);
            }
        }

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

    源码:TransferSolution.zip

    git os china ,为啥不用github,因为速度没有oschina快。https://git.oschina.net/dishiyicijinqiu/TransferSolution/tree/develop

  • 相关阅读:
    复习HTML/CSS 3
    复习HTML/CSS2
    复习HTML/CSS1
    HTML/CSS8
    HTML/CSS7
    HTML/CSS6
    9.5Html
    9.4Html
    面向对象
    作用域以及类、实例
  • 原文地址:https://www.cnblogs.com/dishiyicijinqiu/p/4606880.html
Copyright © 2020-2023  润新知