supersocket实现上传文件

0.先上章效果图吧;

supersocket实现上传文件_第1张图片

1.目录结构:

supersocket实现上传文件_第2张图片

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

你可能感兴趣的:(socket)