Socket通讯工具类【SocketTools】

 

    /// <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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值