Socket通讯工具类【SocketTools】

来源:互联网 发布:js格式视频 编辑:程序博客网 时间:2024/04/30 17:28

 

    /// <summary>    /// Socket通讯工具类    /// 约定:    /// 一个数据包前4个字节为数据长度【长度不包括数据包前面的8个字节】,    /// 中间的4个字节为数据类别: 1为Json,2为文件    /// 后面的均为 “数据”    /// </summary>    public class SocketTools    {        private readonly string mIp;        private readonly int mPort;        private Socket mClient;        /// <summary>        /// 当前连接状态:是否已经连接        /// </summary>        public bool Connected        {            get            {                try                {                    if (this.mClient != null                        && this.mClient.Connected                        && this.mClient.Poll(100, SelectMode.SelectWrite))                    {                        return true;                    }                }                catch (Exception)                { }                return false;            }        }        /// <summary>        /// 构造函数        /// </summary>        /// <param name="ip">ip地址</param>        /// <param name="port">端口号</param>        public SocketTools(string ip, int port)        {            this.mIp = ip;            this.mPort = port;        }        /// <summary>        /// 连接服务器        /// </summary>        /// <returns></returns>        public SocketResult ConnectServer()        {            this.DisConnect();            try            {                //1.创建发送者                this.mClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                //2.连接给谁发送                     this.mClient.Connect(IPAddress.Parse(this.mIp), this.mPort);                this.mClient.SendBufferSize = 102400;                this.mClient.ReceiveBufferSize = 102400;            }            catch (Exception e)            {                return SocketResult.Error(e.Message);            }            return SocketResult.Success();        }        /// <summary>        /// 断开Socket连接        /// </summary>        /// <returns></returns>        public SocketResult DisConnect()        {            try            {                if (this.mClient != null && this.mClient.Connected)                    this.mClient.Close();            }            catch (Exception e)            {                return SocketResult.Error(e.Message);            }            this.mClient = null;            return SocketResult.Success();        }        /// <summary>        /// 向手机端发送Json格式数据,返回Json格式数据        /// </summary>        /// <param name="json"></param>        /// <returns></returns>        public SocketResult SendJsonReceiveJson(SocketModel json)        {            SocketResult tmp = Connect();            if (!tmp.Result)                return tmp;            try            {                SendJson(json);                return ReceiveJson();            }            catch (Exception e)            {                return SocketResult.Error(e.Message);            }        }        /// <summary>        /// 向手机端发送Json格式数据,返回文件        /// 用于下载手机端的文件        /// </summary>        /// <param name="json"></param>        /// <returns></returns>        public SocketResult SendJsonReceiveFile(SocketModel json)        {            SocketResult tmp = Connect();            if (!tmp.Result)                return tmp;            try            {                SendJson(json);                return ReceiveFile();            }            catch (Exception e)            {                return SocketResult.Error(e.Message);            }        }        /// <summary>        /// 向手机端发送文件格式数据,返回Json        /// 向手机端上传文件        /// </summary>        /// <param name="json"></param>        /// <param name="fileName"></param>        /// <returns></returns>        public SocketResult SendFileReceiveModel(SocketModel json, string fileName)        {            SocketResult tmp = Connect();            if (!tmp.Result)                return tmp;            // 先发送Json 后发送文件            try            {                if (!File.Exists(fileName))                {                    return SocketResult.Error("文件不存在");                }                SendJson(json);                SendFile(fileName);                return ReceiveJson();            }            catch (Exception e)            {                return SocketResult.Error(e.Message);            }        }        private SocketResult Connect()        {            if (!this.Connected && this.ConnectServer().Result)            {                return SocketResult.Error("无法连接到手机");            }            return SocketResult.Success();        }        private void SendFile(string fileName)        {            using (FileStream fs = File.OpenRead(fileName))            {                this.mClient.Send(BitConverter.GetBytes((int)fs.Length));                this.mClient.Send(BitConverter.GetBytes(2));//类型2:文件类型                while (fs.Position < fs.Length - 1)                {                    byte[] tempBuffer = new byte[102400];                    int tempLen = fs.Read(tempBuffer, 0, tempBuffer.Length);                    this.mClient.Send(tempBuffer, 0, tempLen, SocketFlags.None);                }                fs.Close();            }        }        private SocketResult ReceiveFile()        {            // read json            MemoryStream ms = this.Read(2);            if (ms == null)            {                return SocketResult.Error("接收数据失败");            }            string tempFile = Path.GetTempFileName();            using (ms)            {                ms.Seek(8, SeekOrigin.Begin);                using (FileStream fs = File.Create(tempFile))                {                    // 循环写入 每次100K                    while (ms.Position < ms.Length - 1)                    {                        byte[] tempBuffer = new byte[102400];                        int tempLen = ms.Read(tempBuffer, 0, tempBuffer.Length);                        fs.Write(tempBuffer, 0, tempLen);                    }                    fs.Flush();                    fs.Close();                }                ms.Close();            }            // 文件下载成功后 将临时文件 文件全路径返回            SocketResult result = SocketResult.Success();            result.Model = new SocketModel();            result.Model.Data.Add("FilePath", tempFile);            return result;        }        private void SendJson(SocketModel json)        {            byte[] data = JsonTools.SerializeToBuffer(json);            if (data == null || data.Length == 0)                throw new ArgumentNullException(" data is empty ");            this.mClient.Send(BitConverter.GetBytes(data.Length));            this.mClient.Send(BitConverter.GetBytes(1));//类型1:json类型            this.mClient.Send(data);        }        private SocketResult ReceiveJson()        {            // read json            MemoryStream ms = this.Read(1);            if (ms == null)            {                return SocketResult.Error("接收数据失败");            }            byte[] buffer = new byte[ms.Length - 8];            ms.Seek(8, SeekOrigin.Begin);            ms.Read(buffer, 0, (int)ms.Length - 8);            ms.Close();            ms.Dispose();            SocketResult socketResult = null;            SocketModel model = JsonTools.DeserializeToTFromBuffer<SocketModel>(buffer);            if (model == null || model.Result == 0)            {                socketResult = SocketResult.Error(model == null ? "接收数据失败" : model.Msg);                socketResult.Model = model;                return socketResult;            }            socketResult = SocketResult.Success();            socketResult.Model = model;            return socketResult;        }        private MemoryStream Read(int type)        {            MemoryStream ms = new MemoryStream();            while (true)            {                int next = GetNextCount(ms);                if (next < 0)                {                    ms = null;                    this.DisConnect();                    break;                }                if (next == 0)                {                    ms.Seek(4, SeekOrigin.Begin);                    byte[] typeBuffer = new byte[4];                    ms.Read(typeBuffer, 0, 4);                    if (type != BitConverter.ToInt32(typeBuffer, 0))                    {                        ms = null;                        this.DisConnect();                    }                    break;                }                long len = ms.Length;                ReadBuffer(ms, next);                // 判断本次读取是否成功                if (ms.Length == len)                {                    ms = null;                    this.DisConnect();                    break;                }            }            return ms;        }        private void ReadBuffer(MemoryStream ms, int next)        {            try            {                byte[] buffer = new byte[next];                int len = 0;                if (this.mClient.Connected)                    len = this.mClient.Receive(buffer, next, SocketFlags.None);                if (len > 0)                {                    ms.Seek(0, SeekOrigin.End);//Seek函数为指定当前MemoryStream的当前位置。这里设置成End是因为:调用本函数的时候,是循环调用往MemoryStream里写入                    ms.Write(buffer, 0, len);                }            }            catch (Exception)            { }        }        private int GetNextCount(MemoryStream ms)        {            // 确定nextCount            int next = 0;            if (ms.Length < 8)            {                next = 8;            }            else            {                ms.Seek(0, SeekOrigin.Begin);                byte[] lenBuffer = new byte[4];                ms.Read(lenBuffer, 0, 4);                try                {                    next = (BitConverter.ToInt32(lenBuffer, 0) + 8 - (int)ms.Length);                }                catch (Exception)                {                    next = int.MinValue;                }            }            // 每次最多读取100K            if (next > 102400)                next = 102400;            return next;        }    }    /// <summary>    /// Socket命令类别    /// </summary>    public enum ESocketCmdType    {        /// <summary>        /// 下载文件        /// </summary>        GetFile = 1,        /// <summary>        /// 获取手机端的照片列表        /// </summary>        GetPicList = 2,        /// <summary>        /// 获取手机端的音乐列表        /// </summary>        GetMusicList = 3,        /// <summary>        /// 获取通讯录列表        /// </summary>        GetAddressListList = 4,        /// <summary>        /// 获取短信列表        /// </summary>        GetSMSList = 5,        /// <summary>        /// 上传文件        /// </summary>        UploadFile = 999,    }    /// <summary>    /// Socket通讯,Json实体类    /// </summary>    public class SocketModel    {        /// <summary>        /// 命令        /// </summary>        [JsonProperty("CMD")]        public ESocketCmdType CMD;        /// <summary>        /// 1:成功 0:失败        /// </summary>        [JsonProperty("Result")]        public int Result;        /// <summary>        /// 提示信息        /// </summary>        [JsonProperty("Msg")]        public string Msg;        /// <summary>        /// 命令附带参数        /// </summary>        [JsonProperty("Data")]        public Dictionary<string, object> Data;        public SocketModel()        {            this.Msg = string.Empty;            this.Data = new Dictionary<string, object>();        }        public SocketModel AddData(string key, object value)        {            if (this.Data != null && !this.Data.ContainsKey(key))                this.Data.Add(key, value);            return this;        }        public string GetString(string key)        {            if (this.Data != null && this.Data.ContainsKey(key) && this.Data[key] != null)                return this.Data[key].ToString().Trim();            return string.Empty;        }        public int GetInt(string key)        {            if (this.Data != null && this.Data.ContainsKey(key))            {                if (this.Data[key] is string)                {                    return int.Parse((this.Data[key] as string).Trim());                }                if (this.Data[key] != null)                {                    return int.Parse(this.Data[key].ToString().Trim());                }            }            return -1;        }        public double GetDouble(string key)        {            if (this.Data != null && this.Data.ContainsKey(key))            {                if (this.Data[key] is string)                {                    return double.Parse((this.Data[key] as string).Trim());                }                if (this.Data[key] != null)                {                    return double.Parse(this.Data[key].ToString().Trim());                }            }            return -1;        }        public Dictionary<string, object> GetDictionary(string key)        {            if (this.Data != null && this.Data.ContainsKey(key))                return JsonTools.Deserialize(this.Data[key]);            return null;        }        public Dictionary<string, string> GetDictionaryString(string key)        {            if (this.Data != null && this.Data.ContainsKey(key))                return JsonTools.DeserializeToTFromObject<Dictionary<string, string>>(this.Data[key]);            return null;        }        public T GetObject<T>(string key) where T : class        {            if (this.Data != null && this.Data.ContainsKey(key))                return JsonTools.DeserializeToTFromObject<T>(this.Data[key]);            return null;        }    }    /// <summary>    /// Socket通讯结果    /// </summary>    public class SocketResult    {        /// <summary>        /// 操作是否成功        /// </summary>        public bool Result;        /// <summary>        /// 失败时的错误提示信息        /// </summary>        public string Msg;        /// <summary>        /// 服务端返回的数据        /// </summary>        public SocketModel Model;        private SocketResult()        { }        public static SocketResult Success()        {            SocketResult result = new SocketResult();            result.Result = true;            result.Msg = "操作成功";            return result;        }        public static SocketResult Error(string msg)        {            SocketResult result = new SocketResult();            result.Result = false;            result.Msg = msg;            return result;        }    }


 

0 0
原创粉丝点击