Socket 接收数据的粘包、断包处理

1、客户端发送打包处理

/// 
    /// 消息包
    ///  
    public class Package
    {
        /// 
        /// 流水号
        /// 
        public string MessageId { get; set; }

        /// 
        ///  公司服务编码  
        /// 
        public int CompanyKey { get; set; }

        /// 
        /// 公司名称
        /// 
        public string CompanyName { get; set; }


        /// 
        ///  JSON字符串
        /// 
        public string JsonStr { get; set; }

        /// 
        ///  请求时间
        /// 
        public DateTime RequestTime { get; set; }
    }
/// 
        /// 发关数据打包
        /// 
        /// 
        /// 
        /// 
        private void SendPacket(string json, string msg, ref int num)
        {
            if (!string.IsNullOrEmpty(json))
            {
                var packet = new Package()
                {
                    MessageId = "2",
                    CompanyKey = DbConfig.CompanyKey,
                    CompanyName = DbConfig.CompanyName,
                    JsonStr = json,
                    RequestTime = DateTime.Now
                };
                var data = JsonConvert.SerializeObject(packet);
                Send(data);
                AddMsgInfo($@"已上传{num}个{msg},包长:{data.Length}");
            }
        }



        /// 
        /// 发送
        /// 
        /// 
        private void Send(string json)
        {
            if (_isConnetion)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(json.Replace("!", "!"));//正文的!全部替换成中文格式
                sb.Append("!"); //包尾标记 使用英文格式。
                byte[] by = Encoding.GetEncoding("GBK").GetBytes(sb.ToString());
                Client.Send(by, by.Length);
            }
            else
            {
                //addMsg("未连接");
                AddMsg("未登录,请先连接平台!");
            }
        }

2、服务端接收粘包处理

 private HandleResult OnCompanyTcpServerReceive(IntPtr connId, IntPtr pData, int length)
        {

            try
            {
                AcquisitionBusiness acquisition = new AcquisitionBusiness();
                var str = Marshal.PtrToStringAnsi(pData);//转字符串
                var plist = HandlerBytesData(str, connId);
                foreach (var result in plist)
                {
                    if (result.MessageId == 1)
                    {
                        string ip = "";
                        ushort port = 0;
                        if (_companyServer.GetRemoteAddress(connId, ref ip, ref port))
                        {
                            if (_companyConnections.Count(p => p.CompanyId == result.CompanyKey.ToString()) > 0)
                            {
                                this._companyConnections.RemoveAll(p => p.CompanyId == result.CompanyKey.ToString());
                            }

                            this._companyConnections.Add(new CompanyConnection()
                            {
                                ConnectionId = connId.ToString(),
                                ConnectionIntPtr = connId,
                                CompanyId = result.CompanyKey.ToString(),
                                Name = result.CompanyName,
                                Ip = ip,
                                Post = port.ToString(),
                                LastTime = DateTime.Now
                            });
                        }
                        ShowConnectionsInfo();
                    }
                    else if (result.MessageId == 2)
                    {
                        var data = JsonConvert.DeserializeObject(result.JsonStr);
                        JToken arro;
                        JToken arrp;
                        JToken arrd;
                        data.TryGetValue("order", out arro);
                        data.TryGetValue("project", out arrp);
                        data.TryGetValue("distribution", out arrd);
                        var cname = result.CompanyName?.ToString() ?? "";

                        if (result.CompanyKey > 0)
                        {
                            if (arro != null && arro.Any())
                            {
                                var torder = arro;
                                var order = torder.ToObject();
                                acquisition.SaveOrder(order, result.CompanyKey, cname);
                                //
                            }

                            if (arrp != null && arrp.Any())
                            {
                                var tproject = arrp;
                                var project = tproject.ToObject();
                                acquisition.SaveProject(project, result.CompanyKey, cname);
                            }

                            if (arrd == null || !arrd.Any()) return HandleResult.Ok;
                            var tdistribution = arrd;
                            var distribution = tdistribution.ToObject();
                            acquisition.SaveDistribution(distribution, result.CompanyKey, cname);

                            plist.Remove(result);
                            return HandleResult.Ok;
                        }
                        else
                        {
                            return HandleResult.Error;
                        }
                    }
                }
                return HandleResult.Error;
            }
            catch (Exception ex)
            {
                _log.Error($"OnCompanyTcpServerReceive 报错=>{ex.Message}");
                return HandleResult.Error;
            }




        }
 /// 
        /// 粘包处理
        /// 
        /// 
        /// 
        /// 
        public List HandlerBytesData(string datas, IntPtr connId)
        {
            var list = new List();
            try
            {
                var sb = _cacheManager.Get(connId.ToString());
                foreach (var data in datas.Split('!').Where(arg => !string.IsNullOrEmpty(arg)))
                {
                    try
                    {
                        Package package = null;

                        try
                        {
                            package = JsonConvert.DeserializeObject(data);
                            list.Add(package);
                        }
                        catch (Exception)
                        {
                            if (sb == null)
                            {
                                sb = new StringBuilder();
                            }
                            if (sb.Length > 0)
                            {
                                sb.Append(data);
                                try
                                {
                                    package = JsonConvert.DeserializeObject(sb.ToString());
                                    sb.Clear();
                                    _cacheManager.Remove(connId.ToString());
                                    list.Add(package);
                                }
                                catch (Exception)
                                {
                                    _cacheManager.Add(connId.ToString(), sb);
                                    continue;
                                }
                            }
                            else
                            {
                                sb.Append(data);
                                _cacheManager.Add(connId.ToString(), sb);
                                continue;
                            }
                     
                        }

                    }
                    catch (Exception e)
                    {
                        _log.Error($" StartListenServer -> 请求数据:{data},异常信息:{e.StackTrace}");
                        return null;
                    }
                }
                return list;

            }
            catch (Exception ex)
            {
                _log.Error($"报错信息=>{ex.Message}\n报错位置:{ex.StackTrace}");
                return null;
            }

        }

        #endregion

    }

 

你可能感兴趣的:(C#)