using SuperSocket.ProtoBase; using System; using System.Buffers; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Waste.Socket { public class MyPackageFilter : FixedHeaderPipelineFilter { /// /// Header size is 2 /// public MyPackageFilter() : base(2) //包头的大小是2字节,所以将2传如基类的构造方法中去 { } /// /// 从数据包的头部返回包体的大小 /// /// /// protected override int GetBodyLengthFromHeader(ref ReadOnlySequence buffer) { int len = 0; var reader = new SequenceReader(buffer); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); string key = reader.ReadString(Encoding.GetEncoding("GB2312")); if (key != "A9") { } else { len = (int)buffer.Length - 2; } return len; } /// /// 将数据包解析成 MyPackage 的实例 /// /// /// protected override MyPackage DecodePackage(ref ReadOnlySequence buffer) { var package = new MyPackage(); var reader = new SequenceReader(buffer); var _reader = reader; Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); package.Str = Tools.GetString(buffer); reader.TryRead(out byte keyByte); string key = keyByte.ByteToHexStr(); if (key != "A9") { var len = buffer.Length; string msg = key; for (var i = 1; i < len; i++) { reader.TryRead(out byte msgByte); msg += msgByte.ByteToHexStr(); } package.IsChecked = false; package.Body = msg; } else { package.Key = key; package.Len = (int)buffer.Length - 2; string body = ""; byte[] bytes = new byte[package.Len]; for (var i = 0; i < package.Len; i++) { reader.TryRead(out byte val); bytes[i] = val; } if (bytes.Length == 1 && bytes[0] == 0) { return null; } Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); body = bytes.BytesToString().Replace("\n", "").Replace("\r", ""); package.Body = body; var arr = body.Split('|'); #region 心跳包的处理,IMEI|GPS if (arr.Length == 2) { package.IsHeart = true; package.IMEI = arr[0]; var gpsarr = arr[1].Split(','); if (gpsarr.Length == 2) { package.Longitude = gpsarr[0]; package.Latitude = gpsarr[1]; } } else if (arr.Length == 7) { package.ICCID = arr[0]; package.IMEI = arr[1]; package.IMSI = arr[2]; package.GSLQ = arr[3]; package.Time = $"{arr[4]}{arr[5]}"; //九方城@前门@厨余垃圾@7.91 var measurearr = arr[6].Split('@'); if (measurearr.Length == 4) { package.City = measurearr[0]; package.Area = measurearr[1]; package.WasteType = measurearr[2]; package.Weight = measurearr[3]; } } #endregion } return package; } } /// /// 转换工具 /// public static class Tools { public static string GetString(in this ReadOnlySequence payload, Encoding encoding = null) { encoding ??= Encoding.UTF8; return payload.IsSingleSegment ? encoding.GetString(payload.FirstSpan) : GetStringSlow(payload, encoding); static string GetStringSlow(in ReadOnlySequence payload, Encoding encoding) { // linearize int length = checked((int)payload.Length); var oversized = ArrayPool.Shared.Rent(length); try { payload.CopyTo(oversized); return encoding.GetString(oversized, 0, length); } finally { ArrayPool.Shared.Return(oversized); } } } /// /// /// /// /// public static string ByteToHexStr(this byte bt) { return ((int)bt).ToString("X2"); } /// /// byte转int /// /// /// public static int ByteToInt(this byte bt) { return Convert.ToInt32(((int)bt).ToString("X2"), 16); } /// /// 字节数组转16进制 /// /// /// public static string BytesToHexStr(this byte[] bt) { string returnStr = ""; if (bt != null) { for (int i = 0; i < bt.Length; i++) { returnStr += bt[i].ToString("X2") + " "; } } return returnStr; } /// /// 字节数组转字符串 /// /// /// public static string BytesToString(this byte[] bytes) { string returnStr = ""; if (bytes != null) { returnStr = Encoding.GetEncoding("GB2312").GetString(bytes); } return returnStr; } /// /// 字节数据转中文 /// /// /// public static string BytesToChsString(this byte[] bytes) { string hex = BytesToHexStr(bytes); if (hex == null) return ""; if (hex.Length % 2 != 0) { hex += "20";//空格 } for (int i = 0; i < bytes.Length; i++) { try { // 每两个字符是一个 byte。 bytes[i] = byte.Parse(hex.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber); } catch { } } // 获得 GB2312,Chinese Simplified。 Encoding chs = Encoding.GetEncoding("gb2312"); return chs.GetString(bytes); } } /// /// 垃圾分类格式解析,传输过来的数据格式类似于:九方城@前门@厨余垃圾@7.91 /// public class WastePackageFilter : PipelineFilterBase { public override MyPackage Filter(ref SequenceReader reader) { try { if(reader.Length <= 0) { return null; } var package = new MyPackage(); var _reader = reader; Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); package.Str = _reader.ReadString(Encoding.GetEncoding("GB2312")); string key = ""; int keylen = 1; #region 解析头部,头部固定为A9 if(reader.Length >= 2) { keylen = 2; byte[] keys = new byte[2]; reader.TryRead(out byte key1Byte); keys[0] = key1Byte; reader.TryRead(out byte key2Byte); keys[1] = key2Byte; key = keys.BytesToString(); } else { byte[] keys = new byte[1]; reader.TryRead(out byte key1Byte); keys[0] = key1Byte; key = keys.BytesToString(); } #endregion if (key != "A9") { var len = reader.Length; string msg = ""; reader.Rewind(keylen); for (var i = 0; i < len; i++) { reader.TryRead(out byte msgByte); msg += msgByte.ByteToHexStr(); } package.IsChecked = false; package.Body = msg; } else { package.Key = key; package.Len = (int)reader.Length - 2; string body = ""; byte[] bytes = new byte[package.Len]; for (var i = 0; i < package.Len; i++) { reader.TryRead(out byte val); bytes[i] = val; } if (bytes.Length == 1 && bytes[0] == 0) { return null; } body = bytes.BytesToString().Replace("\r", "").Replace("\n", ""); package.Body = bytes.BytesToHexStr(); var arr = body.Split('|'); #region 心跳包的处理,IMEI|GPS if (arr.Length == 2) { package.IsHeart = true; package.IMEI = arr[0]; var gpsarr = arr[1].Split(','); if (gpsarr.Length == 2) { package.Longitude = gpsarr[0]; package.Latitude = gpsarr[1]; } } else if (arr.Length == 7) { package.ICCID = arr[0]; package.IMEI = arr[1]; package.IMSI = arr[2]; var gslq = Encoding.GetEncoding("GB2312").GetBytes(arr[3]); if(gslq.Length == 2) { package.GSLQ = Convert.ToInt32(gslq[1]).ToString(); } else { package.GSLQ = gslq.BytesToHexStr(); } package.Time = $"{arr[4]}{arr[5]}".Replace("-","").Replace(":",""); //九方城@前门@厨余垃圾@7.91 var measurearr = arr[6].Split('@'); if (measurearr.Length == 4) { package.City = measurearr[0]; package.Area = measurearr[1]; package.WasteType = measurearr[2]; package.Weight = measurearr[3]; package.IsWeight = true; } else { package.City = arr[6];//临时存放传递过来的数据 } } #endregion } return package; } catch (Exception ex) { Console.WriteLine($"数据处理发生异常:{ex.Message}"); return new MyPackage(); } } } }