using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using static System.Net.WebRequestMethods; using System.Runtime.InteropServices; namespace UdpServerCMD { internal class Program { /// /// 基数【前置位设备数据总数和】 /// //public static int baseNum = 0; public static int length = 0;//接收数据长度 /// /// 在线用户列表 /// public static List idOnLine = new List(); /// /// 存储IP及Socket--便于服务器与指定客户端通信 /// public static Dictionary OnLineDic = new Dictionary(); public static Socket udpServer;//udp服务器 public static bool memberReply;//是否回复消息 //public static TypeFunctionCode LastType = TypeFunctionCode.默认; public static int COMPort = 7000;//端口号 public static string IP1 = "172.16.1.49";//连接IP public static EndPoint serverEnd; //服务端 public static IPEndPoint ipEnd; //发送消息服务端 public static Socket socket; //目标socket public static Thread connectThread; //连接线程 public static byte[] sendData;//发送的数据 static log4net.ILog log; static void Main(string[] args) { //初始化日志 log4net.Config.XmlConfigurator.Configure(); log = log4net.LogManager.GetLogger("loginfo"); //InitSocket(); init(); Console.ReadKey(); } /// /// 发送接口初始化 /// public static void InitSocket(EndPoint endP) { try { //定义连接的服务器ip和端口,可以是本机ip,局域网,互联网 //ipEnd = new IPEndPoint(IPAddress.Parse(IP1), COMPort); ipEnd = (IPEndPoint)(endP); //定义套接字类型,在主线程中定义 socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //定义服务端 IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); serverEnd = (EndPoint)sender; //print("waiting for sending UDP dgram"); //建立初始连接,这句非常重要,第一次连接初始化了serverEnd后面才能收到消息 //SocketSend("connection-successful signal"); } catch (Exception e) { Console.WriteLine("发送初始化:" + e.Message); } } /// /// 发送数据 /// /// public static void SocketSend(string sendStr) { //清空发送缓存 sendData = new byte[1024 * 1024 * 2]; //数据类型转换 //sendData = Encoding.Default.GetBytes(sendStr); StringBuilder stringBuilder = new StringBuilder(""); for (int i = 0; i < sendStr.Length; i++) { if (i != 0 && i % 2 != 0) stringBuilder.Append(sendStr[i] + " "); else stringBuilder.Append(sendStr[i]); } log.Info("发送至 " + ipEnd.ToString() + ": " + stringBuilder); sendData = hexStringToByteArray(sendStr); //发送给指定服务端 socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd); //socket.SendTo(sendData, sendData.Length, SocketFlags.None, new IPEndPoint(IPAddress.Parse(ipEnd.Address.ToString()), 0)); } /// /// 连接关闭 /// public static void SocketQuit() { //关闭线程 if (connectThread != null) { connectThread.Interrupt(); connectThread.Abort(); } //最后关闭socket if (socket != null) socket.Close(); } /// /// 接收接口初始化 /// public static void init() { try { //var IP = "111.229.30.246"; var IP = "172.17.0.9"; //string IP = "172.16.1.49"; int Port = 12301; //建立udp服务器,参数2:udp协议以数据报的方式传输,参数3:UDP协议 udpServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //为服务器绑定IP IPAddress ip = IPAddress.Parse(IP); EndPoint ep = new IPEndPoint(ip, Port); udpServer.Bind(ep); //接收数据 EndPoint endP = new IPEndPoint(IPAddress.Any, 0); string message; byte[] data = new byte[1024 * 1024 * 2]; length = 0; //把数据的来源放到第二个参数上 while (true) { length = udpServer.ReceiveFrom(data, ref endP); //message = Encoding.Default.GetString(data, 0, length); message = byteArrayToHexString(data, length); log.Info("接收到 " + endP.ToString() + ": " + message); message = message.Replace(" ", ""); InitSocket(endP); Console.WriteLine("地址:" + endP.ToString() + "\n"); int baseNum = 0;//基数【前置位设备数据总数和】 var LoginFrame = message[20].ToString() + message[21].ToString();//功能码C JudgmentFunctionCode(LoginFrame, message, baseNum); } } catch (Exception e) { Console.WriteLine("接收初始化:" + e.Message); } } /// /// byte[]直接转Float** /// /// /// public static float byteToFloat(string message) { byte[] bFxianOrg = new byte[4]; var a = stringToByteArray(message, Encoding.Default); StringBuilder zz = new StringBuilder(""); StringBuilder _zz = new StringBuilder(""); string[] s = new string[4]; int x = 0; for (int i = 0; i < a.Length; i++) { if (x != 0 && i % 2 == 0) { zz.Append(int.Parse(hexStr2Str(_zz.ToString())).ToString()).Append("-"); _zz.Clear(); x = 0; } _zz.Append(((char)a[i]).ToString()); if (i == a.Length - 1) { zz.Append(int.Parse(hexStr2Str(_zz.ToString())).ToString()).Append("-"); _zz.Clear(); } x++; } s = zz.ToString().Split('-'); byte a0 = byte.Parse(s[0].ToString()); byte a1 = byte.Parse(s[1].ToString()); byte a2 = byte.Parse(s[2].ToString()); byte a3 = byte.Parse(s[3].ToString()); bFxianOrg = new byte[4] { a0, a1, a2, a3 }; var b = BitConverter.ToSingle(bFxianOrg, 0); return b; } /// /// 16进制转字符串(十进制)** /// /// /// public static string hexStr2Str(String hexStr) { String str = "0123456789ABCDEF"; char[] hexs = hexStr.ToCharArray(); byte[] bytes = new byte[hexStr.Length / 2]; int n; for (int i = 0; i < bytes.Length; i++) { n = str.IndexOf(hexs[2 * i]) * 16; n += str.IndexOf(hexs[2 * i + 1]); bytes[i] = (byte)(n & 0xff); } StringBuilder stringBuilder = new StringBuilder(""); for (int i = 0; i < bytes.Length; i++) { stringBuilder.Append(bytes[i]); } return (stringBuilder.ToString()); } /// /// 16进制转ASCII码** /// /// 16进制字符 /// public static StringBuilder hexToASCII(string hexStr) { String str = "0123456789ABCDEF"; char[] hexs = hexStr.ToCharArray(); byte[] bytes = new byte[hexStr.Length / 2]; int n; for (int i = 0; i < bytes.Length; i++) { n = str.IndexOf(hexs[2 * i]) * 16; n += str.IndexOf(hexs[2 * i + 1]); bytes[i] = (byte)(n & 0xff); } StringBuilder VersionNumber = new StringBuilder(""); for (int i = 0; i < bytes.Length; i++) { VersionNumber.Append((char)bytes[i]); } return VersionNumber; } /// /// 获取高四位** /// /// /// public static int getHeight4(byte data) { int height; height = ((data & 0xf0) >> 4); return height; } /// /// 获取低四位** /// /// /// public static int getLow4(byte data) { int low; low = (data & 0x0f); return low; } /// /// //16进制转2进制 /// /// /// public static string HexString2BinString(string hexString) { try { string result = string.Empty; foreach (char c in hexString) { int v = Convert.ToInt32(c.ToString(), 16); int v2 = int.Parse(Convert.ToString(v, 2)); // 去掉格式串中的空格,即可去掉每个4位二进制数之间的空格, result += string.Format("{0:d4} ", v2); } return result; } catch (Exception ex) { Console.WriteLine(ex.Message); throw; } } /// /// 二进制算术累加**【计算校验位/码CS】 /// /// 起始 /// 终止 /// “控制位”“数据位”所有数据 /// public static string binAccumulation(int j, int k, string message) { StringBuilder parityBitCS = new StringBuilder("");//校验位CS --“控制位”、“数据位”的各字节进行二进制算术累加,不计超过 0xFF 的溢出值 long _parityBitCS = 0; int x = 0; for (int i = j; i <= k; i++) { if (x % 2 == 0 && x != 0) { var a = hexStr2Str(parityBitCS.ToString()); _parityBitCS += int.Parse(a); parityBitCS.Clear(); x = 0; } parityBitCS.Append(message[i]); if (i == k) { var a = hexStr2Str(parityBitCS.ToString()); _parityBitCS += int.Parse(a); } x++; } _parityBitCS = _parityBitCS & Convert.ToInt64("FF", 16); return _parityBitCS.ToString("X2"); } /// /// 每8bit高低位互换 /// /// 起始 /// 终止 /// 需要转换的16进制数据 /// 新的16进制数据 public static string interconvert(int j, int k, string message, bool exchange = true) { StringBuilder parityBitCS = new StringBuilder("");//互换后的值 //StringBuilder _parityBitH = new StringBuilder("");//高字节 //StringBuilder _parityBitL = new StringBuilder("");//低字节 //StringBuilder _parityBit = new StringBuilder("");//记录当前字节 //int x = 0; //for (int i = j; i <= k; i++)//?? //{ // if (x == 4) // { // _parityBitL.Append(_parityBit);//记录低字节 // parityBitCS.Append(_parityBitL).Append(_parityBitH);//低字节--高字节 // _parityBitL.Clear();//清空低字节 // _parityBitH.Clear();//清空高字节 // _parityBit.Clear(); // x = 0; // } // else if (x == 2)//记录高字节 // { // _parityBitH.Append(_parityBit); // _parityBit.Clear(); // } // _parityBit.Append(message[i]); // if (i == k) // { // _parityBitL.Append(_parityBit);//记录低字节 // parityBitCS.Append(_parityBitL).Append(_parityBitH);//低字节--高字节 // } // x++; //} string[] strings = new string[4] { message[0].ToString() + message[1].ToString(), message[2].ToString() + message[3].ToString(), message[4].ToString() + message[5].ToString(), message[6].ToString() + message[7].ToString() }; for (int i = strings.Length - 1; i >= 0; i--) { parityBitCS.Append(strings[i].ToString()); } return Convert.ToInt32(parityBitCS.ToString(), 16).ToString(); } #region 暂存 /// /// byte数组转string /// /// /// public static string byteArrayToString(byte[] data, Encoding encoding) { return encoding.GetString(data); } /// /// string转 byte数组 /// /// /// public static byte[] stringToByteArray(string data, Encoding encoding) { return encoding.GetBytes(data); } /// /// byte数组转16进制字符串 /// /// /// public static string byteArrayToHexString(byte[] data, int length = 0) { int dataLength = 0; if (length != 0) dataLength = length; else dataLength = data.Length; StringBuilder builder = new StringBuilder(); for (int i = 0; i < dataLength; i++) { builder.Append(string.Format("{0:X2} ", data[i])); } return builder.ToString().Trim(); } /// /// 16进制字符串转byte数组 /// /// /// public static byte[] hexStringToByteArray(string data) { //string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); List chars = new List(); for (int i = 0; i < data.Length; i++) { chars.Add(data[i].ToString()); } //byte[] _returnBytes = new byte[chars.Count]; byte[] returnBytes = new byte[chars.Count / 2]; //逐个字符变为16进制字节数据 for (int i = 0; i < chars.Count; i++) { try { if (i % 2 == 0) { returnBytes[i / 2] = (byte)(Convert.ToByte(chars[i].ToString() + chars[i + 1].ToString(), 16)); } } catch (Exception e) { //var a = hexStr2Str(chars[i]); //short b = short.Parse(a); //byte c = (byte)(b % 256); //returnBytes[i] = c; Console.WriteLine(e.Message); } } return returnBytes; } /// /// byte数组转10进制字符串 /// /// /// public static string byteArrayToDecString(byte[] data) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < data.Length; i++) { builder.Append(data[i] + " "); } return builder.ToString().Trim(); } /// /// 10进制字符串转byte数组 /// /// /// public static byte[] decStringToByteArray(string data) { string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); byte[] returnBytes = new byte[chars.Length]; //逐个字符变为10进制字节数据 for (int i = 0; i < chars.Length; i++) { returnBytes[i] = Convert.ToByte(chars[i], 10); } return returnBytes; } /// /// byte数组转八进制字符串 /// /// /// public static string byteArrayToOtcString(byte[] data) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < data.Length; i++) { builder.Append(Convert.ToString(data[i], 8) + " "); } return builder.ToString().Trim(); } /// /// 八进制字符串转byte数组 /// /// /// public static byte[] otcStringToByteArray(string data) { string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); byte[] returnBytes = new byte[chars.Length]; //逐个字符变为8进制字节数据 for (int i = 0; i < chars.Length; i++) { returnBytes[i] = Convert.ToByte(chars[i], 8); } return returnBytes; } /// /// 二进制字符串转byte数组 /// /// /// public static byte[] binStringToByteArray(string data) { string[] chars = data.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); byte[] returnBytes = new byte[chars.Length]; //逐个字符变为2进制字节数据 for (int i = 0; i < chars.Length; i++) { returnBytes[i] = Convert.ToByte(chars[i], 2); } return returnBytes; } /// /// byte数组转二进制字符串 /// /// /// public static string byteArrayToBinString(byte[] data) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < data.Length; i++) { builder.Append(Convert.ToString(data[i], 2) + " "); } return builder.ToString().Trim(); } #endregion #region 正向解析 /// /// 登录帧解析 /// /// public static void LoginFrameAnalysis(string message, IPEndPoint ipEnd, Socket socket) { #region 登录帧解析 StringBuilder DataLength = new StringBuilder("");//数据部长度L for (int i = 4; i <= 7; i++) { DataLength.Append(message[i]); } int.Parse(hexStr2Str(DataLength.ToString())); //Console.WriteLine("数据部长度:" + int.Parse(hexStr2Str(DataLength.ToString()))); StringBuilder SimID = new StringBuilder(""); //客户端地址A -- 11位时编码需在最后一字节低四位补 F if (message[19].ToString() == "F") { for (int i = 8; i < 19; i++) { SimID.Append(message[i]); } } else { for (int i = 8; i <= 19; i++) { SimID.Append(message[i]); } } //Console.WriteLine("客户端地址:" + SimID); StringBuilder _voltage = new StringBuilder("");//电压 --缩小10 倍为实际数值 float voltage;//电压 for (int i = 22; i <= 23; i++) { _voltage.Append(message[i]); } voltage = float.Parse(_voltage.ToString()) / 10; //Console.WriteLine("电压:" + voltage); StringBuilder _signal = new StringBuilder("");//信号 --信号为整数 int signal; for (int i = 24; i <= 25; i++) { _signal.Append(message[i]); } signal = int.Parse(_signal.ToString()); //Console.WriteLine("信号:" + signal); StringBuilder date = new StringBuilder("20");//日期 --(BCD 码) for (int i = 26; i <= 37; i++) { if (i == 27 || i == 29) date.Append(message[i] + "-"); else if (i == 31) date.Append(message[i] + " "); else if (i == 33 || i == 35) date.Append(message[i] + ":"); else date.Append(message[i]); } //Console.WriteLine("日期:" + date); StringBuilder workPattern = new StringBuilder("");//工作模式 --0x00 定时开机,0x01 实时在线 for (int i = 38; i <= 39; i++) { workPattern.Append(message[i]); } //switch ((TypeworkPattern)int.Parse(workPattern.ToString())) //{ // case TypeworkPattern.定时开机: // Console.WriteLine(TypeworkPattern.定时开机); // break; // case TypeworkPattern.实时在线: // Console.WriteLine(TypeworkPattern.实时在线); // break; // default: // break; //} StringBuilder _meterNumber = new StringBuilder("");//仪表数量 StringBuilder meterNumber = new StringBuilder("");//仪表数量 for (int i = 40; i <= 41; i++) { _meterNumber.Append(message[i]); } meterNumber.Append(int.Parse(_meterNumber.ToString()).ToString() + "台"); //Console.WriteLine("仪表数量:" + meterNumber); StringBuilder positionNumber = new StringBuilder("");//位置号 --取低 4 位为实际值 for (int i = 42; i <= 43; i++) { //if (i == 42) continue;//取低 4 位为实际值 positionNumber.Append(message[i]); } //Console.WriteLine("位置号:" + getLow4(byte.Parse(hexStr2Str(positionNumber.ToString()))) + "号"); StringBuilder phenotype = new StringBuilder("");//表型 for (int i = 44; i <= 45; i++) { phenotype.Append(message[i]); } //typePheno(phenotype); StringBuilder versionMumber = new StringBuilder("");//版本号 --开始字节4A for (int i = 46; i <= 87; i++) { if (i == 46 || i == 47) continue; versionMumber.Append(message[i]); } versionMumber = hexToASCII(versionMumber.ToString()); //Console.WriteLine("版本号" + versionMumber); StringBuilder reportingCycle = new StringBuilder("");//上报周期 --开始字节4B。115 :15分钟 ,130:30 分钟,24:24小时 for (int i = 88; i <= 91; i++) { if (i == 88 || i == 89) continue; reportingCycle.Append(message[i]); } //if (int.Parse(hexStr2Str(reportingCycle.ToString())) != 24) //{ // var v = new StringBuilder(hexStr2Str(reportingCycle.ToString())); // v.Remove(0, 2); // Console.WriteLine("上报周期: " + v + "h"); //} //else if (int.Parse(hexStr2Str(reportingCycle.ToString())) == 24) //{ // Console.WriteLine("上报周期: " + int.Parse(hexStr2Str(reportingCycle.ToString())) + "h"); //} StringBuilder acquisitionCycle = new StringBuilder("");//采集周期 --开始字节4C。高字节在前,单位:秒 for (int i = 92; i <= 97; i++) { if (i == 92 || i == 93) continue; acquisitionCycle.Append(message[i]); } Convert.ToInt64(acquisitionCycle.ToString(), 16); //Console.WriteLine("采集周期:" + Convert.ToInt64(acquisitionCycle.ToString(), 16) / 60 + "分钟"); StringBuilder factoryCode = new StringBuilder("");//出厂编码 --开始字节4D。ASCII码 for (int i = 98; i <= 127; i++) { if (i == 98 || i == 99) continue; factoryCode.Append(message[i]); } hexToASCII(factoryCode.ToString()); //Console.WriteLine("出厂编码:" + hexToASCII(factoryCode.ToString())); StringBuilder retain = new StringBuilder("");//保留 --开始字节4F。不做处理 for (int i = 128; i <= 145; i++) { if (i == 128 || i == 129) continue; retain.Append(message[i]); } //CRC校验 StringBuilder builder = new StringBuilder(""); for (int i = message.Length - 6; i < message.Length - 4; i++) { builder.Append(message[i]); } if (binAccumulation(4, 145, message).ToUpper() != builder.ToString().ToUpper()) { Console.WriteLine("接收数据校验失败" + ": " + message); log.Info("登录帧校验失败" + ": " + message); return; } Console.WriteLine("数据部长度:" + int.Parse(hexStr2Str(DataLength.ToString()))); Console.WriteLine("客户端地址:" + SimID); Console.WriteLine("电压:" + voltage); Console.WriteLine("信号:" + signal); Console.WriteLine("日期:" + date); switch ((TypeworkPattern)int.Parse(workPattern.ToString())) { case TypeworkPattern.定时开机: Console.WriteLine(TypeworkPattern.定时开机); break; case TypeworkPattern.实时在线: Console.WriteLine(TypeworkPattern.实时在线); break; default: break; } Console.WriteLine("仪表数量:" + meterNumber); Console.WriteLine("位置号:" + getLow4(byte.Parse(hexStr2Str(positionNumber.ToString()))) + "号"); typePheno(phenotype); Console.WriteLine("版本号" + versionMumber); if (int.Parse(hexStr2Str(reportingCycle.ToString())) != 24) { var v = new StringBuilder(hexStr2Str(reportingCycle.ToString())); v.Remove(0, 2); Console.WriteLine("上报周期: " + v + "h"); } else if (int.Parse(hexStr2Str(reportingCycle.ToString())) == 24) { Console.WriteLine("上报周期: " + int.Parse(hexStr2Str(reportingCycle.ToString())) + "h"); } Console.WriteLine("采集周期:" + Convert.ToInt64(acquisitionCycle.ToString(), 16) / 60 + "分钟"); Console.WriteLine("出厂编码:" + hexToASCII(factoryCode.ToString())); Console.WriteLine("校验位CS:" + binAccumulation(4, 145, message)); #endregion longinDecompilation(SimID, ipEnd, socket); } /// /// 数据帧1解析 /// /// /// 基数【前置位设备数据总数和】 public static void dataFramesAnalysis(string message, string code, int baseNum) { basicsAnalysis(message); Isgo(message, baseNum); sendClock(message); } /// /// 时钟解析 /// /// public static void clockAnalysis(string message, IPEndPoint ipEnd) { StringBuilder DataLength = new StringBuilder("");//数据部长度L for (int i = 4; i <= 7; i++) { DataLength.Append(message[i]); } int.Parse(hexStr2Str(DataLength.ToString())); Console.WriteLine("数据部长度:" + int.Parse(hexStr2Str(DataLength.ToString()))); StringBuilder SimID = new StringBuilder(""); //客户端地址A -- 11位时编码需在最后一字节低四位补 F if (message[19].ToString() == "F") { for (int i = 8; i < 19; i++) { SimID.Append(message[i]); } } else { for (int i = 8; i <= 19; i++) { SimID.Append(message[i]); } } Console.WriteLine("客户端地址:" + SimID); StringBuilder _clock = new StringBuilder(""); StringBuilder clock = new StringBuilder("");//时钟 --年只取后两位 for (int i = 22; i <= 33; i++) { _clock.Append(message[i]); } for (int i = 0; i < 6; i++) { if (i == 0) { clock.Append(hexStr2Str(_clock.ToString()[0].ToString() + _clock.ToString()[1].ToString())); clock.Append("-"); } else { clock.Append(hexStr2Str(_clock.ToString()[i * 2].ToString() + _clock.ToString()[i * 2 + 1].ToString())); if (i == 1) clock.Append("-"); else if (i == 2) clock.Append(" "); else if (i == 3) clock.Append(":"); else if (i == 4) clock.Append(":"); } } Console.WriteLine("时钟:20" + clock); StringBuilder sig = new StringBuilder("");//有无后续帧标识 --0 无后续帧 1 有后续帧 for (int i = 34; i <= 35; i++) { sig.Append(message[i]); } if (sig.ToString() == "00") Console.WriteLine("无后续帧"); else Console.WriteLine("有后续帧"); StringBuilder parityBitCS = new StringBuilder("");//校验位CS --“控制位”、“数据位”的各字节进行二进制算术累加,不计超过 0xFF 的溢出值 parityBitCS.Append(binAccumulation(4, 35, message.ToString())); Console.WriteLine("校验位CS:" + parityBitCS); } #endregion #region 反编译 /// /// 登录帧反编译 /// /// 客户端地址A public static void longinDecompilation(StringBuilder SimID, IPEndPoint ipEnd, Socket socket) { if (SimID.Length == 11) SimID.Append("F"); StringBuilder parityBitCS = new StringBuilder(""); StringBuilder message = new StringBuilder("403A" + "0009" + SimID + "01" + "00"); parityBitCS.Append(binAccumulation(4, 23, message.ToString())); var a = message.Append(parityBitCS).ToString() + "0D0A"; SocketSend(a); } /// /// 数据帧反编译 /// /// sim码 /// 功能码 /// 版本号 public static void dataFramesDecompilation(StringBuilder SimID, string code, IPEndPoint ipEnd, Socket socket, string versionNum = "01") { if (SimID.Length == 11) SimID.Append("F"); StringBuilder parityBitCS = new StringBuilder(""); StringBuilder message = new StringBuilder("403A" + "000B" + SimID + code + versionNum + "0100"); parityBitCS.Append(binAccumulation(4, 27, message.ToString())); SocketSend(message.Append(parityBitCS) + "0D0A"); } /// /// 发送时钟校验 /// /// public static void sendClock(string message) { StringBuilder SimID = new StringBuilder(""); //客户端地址A -- 11位时编码需在最后一字节低四位补 F for (int i = 8; i <= 19; i++) { SimID.Append(message[i]); } StringBuilder parityBitCS = new StringBuilder("");//校验位CS --“控制位”、“数据位”的各字节进行二进制算术累加,不计超过 0xFF 的溢出值 StringBuilder Clock = new StringBuilder("");//时钟 --年只取后两位 Clock.Append(getClock()); StringBuilder sig = new StringBuilder("00");//有无后续帧标识 --0 无后续帧 1 有后续帧 StringBuilder msg = new StringBuilder("403A" + "000F" + SimID + "05" + Clock + sig); parityBitCS.Append(binAccumulation(4, 35, msg.ToString())); SocketSend(msg.Append(parityBitCS).ToString() + "0D0A"); } /// /// 获取当前时钟的16进制【年只取后两位】 /// /// public static string getClock() { StringBuilder builder = new StringBuilder(""); string str = DateTime.Now.ToString(); string[] strings = str.Split(':', '/', ' '); for (int i = 0; i < strings.Length; i++) { if (strings[i].Length == 1) strings[i] = 0 + strings[i].ToString(); } for (int i = 0; i < strings.Length; i++) { if (i == 0) builder.Append(int.Parse(strings[i][2].ToString() + strings[i][3].ToString()).ToString("X2").ToString()); else builder.Append(int.Parse(strings[i]).ToString("X2").ToString()); } return builder.ToString(); } #endregion /// /// 基础解析【长度--采集时间】 /// /// public static void basicsAnalysis(string message) { #region 长度--采集时间 StringBuilder DataLength = new StringBuilder("");//数据部长度L for (int i = 4; i <= 7; i++) { DataLength.Append(message[i]); } int.Parse(hexStr2Str(DataLength.ToString())); Console.WriteLine("数据部长度:" + int.Parse(hexStr2Str(DataLength.ToString()))); StringBuilder SimID = new StringBuilder(""); //客户端地址A -- 11位时编码需在最后一字节低四位补 F if (message[19].ToString() == "F") { for (int i = 8; i < 19; i++) { SimID.Append(message[i]); } } else { for (int i = 8; i <= 19; i++) { SimID.Append(message[i]); } } Console.WriteLine("客户端地址:" + SimID); StringBuilder totalFrames = new StringBuilder("");//总帧数 for (int i = 22; i <= 23; i++) { totalFrames.Append(message[i]); } Console.WriteLine("总帧数:" + int.Parse(totalFrames.ToString())); StringBuilder whichFrame = new StringBuilder("");//第几帧 for (int i = 24; i <= 25; i++) { whichFrame.Append(message[i]); } Console.WriteLine("第几帧:" + int.Parse(whichFrame.ToString())); StringBuilder currentFrame = new StringBuilder(""); //此帧表数 for (int i = 26; i <= 27; i++) { currentFrame.Append(message[i]); } Console.WriteLine("此帧表数:" + int.Parse(currentFrame.ToString())); #region 暂存 //StringBuilder platForm = new StringBuilder("");//站号 --十进制减去64 为实际数值 //for (int i = 28; i <= 29; i++) //{ // platForm.Append(message[i]); //} //var _platForm = int.Parse(hexStr2Str(platForm.ToString())) - 64; //Console.WriteLine("站号:" + _platForm); //StringBuilder phenotype = new StringBuilder("");//表型 //for (int i = 30; i <= 31; i++) //{ // phenotype.Append(message[i]); //} //StringBuilder _phenotype = new StringBuilder("");//--表型数字 81 83 84 ////_phenotype.Clear().Append(typePheno(phenotype)); //StringBuilder alarmCode = new StringBuilder("");//报警码 //for (int i = 32; i <= 33; i++) //{ // alarmCode.Append(message[i]); //} //typeAlarmcode(alarmCode); //StringBuilder date = new StringBuilder("20");//采集时间 --(BCD 码) //for (int i = 34; i <= 43; i++) //{ // if (i == 35 || i == 37) date.Append(message[i] + "-"); // else if (i == 39) date.Append(message[i] + " "); // else if (i == 41) date.Append(message[i] + ":"); // else date.Append(message[i]); //} //Console.WriteLine("采集时间:" + date); #endregion #endregion } /// /// 判断后面是否存在仪表数据【有继续】 /// /// /// 表型起始位下标 22 + 6 + baseNum + 2 /// 表型终止位下标 22 + 6 + baseNum + 3 /// 基数【前置位设备数据总数和】 public static void Isgo(string message, int baseNum) { try { if (message.Length >= 31 + baseNum) { StringBuilder go = new StringBuilder(message[30 + baseNum].ToString() + message[31 + baseNum].ToString());//表型 var code = message[20].ToString() + message[21].ToString();//功能码C StringBuilder SimID = new StringBuilder(""); //客户端地址A -- 11位时编码需在最后一字节低四位补 F if (message[19].ToString() == "F") { for (int i = 8; i < 19; i++) { SimID.Append(message[i]); } } else { for (int i = 8; i <= 19; i++) { SimID.Append(message[i]); } } if (go.ToString() == "84") { Console.WriteLine(); phenotype84(message, baseNum); dataFramesDecompilation(SimID, code, ipEnd, socket); } else if ((go.ToString() == "83")) { Console.WriteLine(); phenotype83(message, baseNum); dataFramesDecompilation(SimID, code, ipEnd, socket); } else if ((go.ToString() == "81")) { Console.WriteLine(); phenotype81(message, baseNum); dataFramesDecompilation(SimID, code, ipEnd, socket); } } } catch (Exception e) { Console.WriteLine(e.Message.ToString()); } } /// /// 0x81、0x83、0x84共用解析【站号、表型 、报警码、采集时间】 /// /// /// 基数(前所有位合计) public static void shareAnalysis(string message, int multiplier) { StringBuilder platForm = new StringBuilder("");//站号 --十进制减去64 为实际数值 for (int i = 28 + multiplier; i <= 29 + multiplier; i++) { platForm.Append(message[i]); } var _platForm = int.Parse(hexStr2Str(platForm.ToString())) - 64; Console.WriteLine("站号:" + _platForm); StringBuilder phenotype = new StringBuilder("");//表型 for (int i = 30 + multiplier; i <= 31 + multiplier; i++) { phenotype.Append(message[i]); } StringBuilder _phenotype = new StringBuilder("");//--表型数字 81 83 84 _phenotype.Clear().Append(typePheno(phenotype)); StringBuilder alarmCode = new StringBuilder("");//报警码 for (int i = 32 + multiplier; i <= 33 + multiplier; i++) { alarmCode.Append(message[i]); } typeAlarmcode(alarmCode); StringBuilder date = new StringBuilder("20");//采集时间 --(BCD 码) for (int i = 34 + multiplier; i <= 43 + multiplier; i++) { if (i == 35 + multiplier || i == 37 + multiplier) date.Append(message[i] + "-"); else if (i == 39 + multiplier) date.Append(message[i] + " "); else if (i == 41 + multiplier) date.Append(message[i] + ":"); else date.Append(message[i]); } Console.WriteLine("采集时间:" + date); } /// /// 表型81 /// /// /// 基数【前置位设备数据总数和】 public static void phenotype81(string message, int baseNum) { int multiplier;//基数(前所有位合计) if (baseNum != 0) { //var multiplier = (whatFrame - 1) * 84; multiplier = baseNum; baseNum += (68 + 16); } else { multiplier = 0; baseNum = (68 + 16); } //shareAnalysis(message, multiplier); StringBuilder validity = new StringBuilder("");//抄表数据有效 --无符号整型,0x26 有效,其他无效 for (int i = 44 + multiplier; i <= 45 + multiplier; i++) { validity.Append(message[i]); } //if (validity.ToString() == "26") //{ // Console.WriteLine("抄表数据有效"); //} //else //{ // Console.WriteLine("抄表数据无效"); //} StringBuilder versionNum = new StringBuilder(""); //版本号 --整型 for (int i = 46 + multiplier; i <= 47 + multiplier; i++) { versionNum.Append(message[i]); } //Console.WriteLine("版本号:" + int.Parse(versionNum.ToString())); StringBuilder instantaneousFlow = new StringBuilder("");//瞬时流量 --浮点型,缩小 1000 倍为实际值,单位: m3/h for (int i = 48 + multiplier; i <= 55 + multiplier; i++) { instantaneousFlow.Append(message[i]); } var _instantaneousFlow = byteToFloat(instantaneousFlow.ToString()) / 1000; //Console.WriteLine("瞬时流量" + _instantaneousFlow.ToString() + "m3/h"); StringBuilder _positiveFlow = new StringBuilder("");//累积流量 --带符号整型,低字节在前,高字节在后,缩小 10 倍为实际数值,单位: m3。 for (int i = 56 + multiplier; i <= 63 + multiplier; i++) { _positiveFlow.Append(message[i]); } int positiveFlow = int.Parse(/*hexStr2Str*/(interconvert(56 + multiplier, 63 + multiplier, _positiveFlow.ToString()))) / 10;//??? //Console.WriteLine("累积流量:" + positiveFlow + "m3"); StringBuilder waterTemperature = new StringBuilder("");//水温 --浮点型,单位: ℃ for (int i = 64 + multiplier; i <= 71 + multiplier; i++) { waterTemperature.Append(message[i]); } var _waterTemperature = byteToFloat(waterTemperature.ToString());//??? //Console.WriteLine("水温:" + _waterTemperature + "℃"); StringBuilder _RunTime = new StringBuilder("");//累积运行时间 --带符号整型,低字节在前,高字节在后,单位: h for (int i = 72 + multiplier; i <= 79 + multiplier; i++) { _RunTime.Append(message[i]); } int RunTime = int.Parse(/*hexStr2Str*/(interconvert(72 + multiplier, 79 + multiplier, _RunTime.ToString())));//??? //Console.WriteLine("累积运行时间:" + RunTime + "h"); StringBuilder _cellVoltage = new StringBuilder("");//电池电压 --浮点型,低字节在前,高字节在后,单位: v。 for (int i = 80 + multiplier; i <= 87 + multiplier; i++) { _cellVoltage.Append(message[i]); } //float cellVoltage = float.Parse(/*hexStr2Str*/(interconvert(80 + multiplier, 87 + multiplier, _cellVoltage.ToString()))); float cellVoltage = byteToFloat(_cellVoltage.ToString());//??? //Console.WriteLine("电池电压:" + cellVoltage + "v"); StringBuilder _pipeSize = new StringBuilder("");//管径 --浮点型,单位: mm for (int i = 88 + multiplier; i <= 95 + multiplier; i++) { _pipeSize.Append(message[i]); } //float pipeSize = float.Parse(_pipeSize.ToString()); float pipeSize = byteToFloat(_pipeSize.ToString());//??? //Console.WriteLine("管径:" + pipeSize + "mm"); StringBuilder capacity = new StringBuilder("");//量程 --长整型,单位:单位缺失。 for (int i = 96 + multiplier; i <= 103 + multiplier; i++) { capacity.Append(message[i]); } //Console.WriteLine("量程:" + interconvert(0, 0, capacity.ToString()));//??? StringBuilder dampingFactor = new StringBuilder("");//阻尼系数 --ASCII 码 for (int i = 104 + multiplier; i <= 105 + multiplier; i++) { dampingFactor.Append(message[i]); } //Console.WriteLine("阻尼系数:" + hexToASCII(dampingFactor.ToString())); StringBuilder InstrumentType = new StringBuilder("");//仪表类型 for (int i = 106 + multiplier; i <= 107 + multiplier; i++) { InstrumentType.Append(message[i]); } StringBuilder diagnose = new StringBuilder("");//诊断代码(仪表故障码) --当设备上报 0x06 故障时,不应再上报其他故障。 for (int i = 108 + multiplier; i <= 109 + multiplier; i++) { diagnose.Append(message[i]); } //typeMalfunction(diagnose); //CRC校验 StringBuilder builder = new StringBuilder(""); for (int i = 112 + multiplier; i <= 113 + multiplier; i++) { builder.Append(message[i]); } if (binAccumulation(4 + multiplier, 111 + multiplier, message).ToUpper() != builder.ToString().ToUpper()) { Console.WriteLine("接收数据校验失败" + ": " + message); log.Info("登录帧校验失败" + ": " + message); Isgo(message, baseNum); return; } shareAnalysis(message, multiplier); if (validity.ToString() == "26") { Console.WriteLine("抄表数据有效"); } else { Console.WriteLine("抄表数据无效"); } Console.WriteLine("版本号:" + int.Parse(versionNum.ToString())); Console.WriteLine("瞬时流量" + _instantaneousFlow.ToString() + "m3/h"); Console.WriteLine("累积流量:" + positiveFlow + "m3"); Console.WriteLine("水温:" + _waterTemperature + "℃"); Console.WriteLine("累积运行时间:" + RunTime + "h"); Console.WriteLine("电池电压:" + cellVoltage + "v"); Console.WriteLine("管径:" + pipeSize + "mm"); Console.WriteLine("量程:" + interconvert(0, 0, capacity.ToString()));//??? typeMalfunction(diagnose); //数据校验 --版本号-故障代码 Console.WriteLine("数据校验:" + binAccumulation(46 + multiplier, 109 + multiplier, message));//版本号--故障码 Console.WriteLine("校验位CS:" + binAccumulation(4 + multiplier, 111 + multiplier, message));//数据部长度--数据校验 Isgo(message, baseNum); } /// /// 表型83 /// /// /// 基数【前置位设备数据总数和】 public static void phenotype83(string message, int baseNum) { int multiplier; if (baseNum != 0) { //var multiplier = (whatFrame - 1) * 84; multiplier = baseNum; baseNum += (84 + 16); } else { multiplier = 0; baseNum = (84 + 16); } //shareAnalysis(message, multiplier); StringBuilder validity = new StringBuilder("");//抄表数据有效 --无符号整型,0x26 有效,其他无效 for (int i = 44 + multiplier; i <= 45 + multiplier; i++) { validity.Append(message[i]); } //if (validity.ToString() == "26") //{ // Console.WriteLine("抄表数据有效"); //} //else //{ // Console.WriteLine("抄表数据无效"); //} StringBuilder versionNum = new StringBuilder(""); //版本号 --整型 for (int i = 46 + multiplier; i <= 47 + multiplier; i++) { versionNum.Append(message[i]); } //Console.WriteLine("版本号:" + int.Parse(versionNum.ToString())); StringBuilder instantaneousFlow = new StringBuilder("");//瞬时流量 --浮点型,缩小 1000 倍为实际值,单位: m3/h for (int i = 48 + multiplier; i <= 55 + multiplier; i++) { instantaneousFlow.Append(message[i]); } //Console.WriteLine("瞬时流量" + float.Parse(instantaneousFlow.ToString()) / 1000 + "m3/h");//??? //Console.WriteLine("瞬时流量" + byteToFloat(instantaneousFlow.ToString()) / 1000 + "m3/h"); StringBuilder _positiveFlow = new StringBuilder("");//正累积流量 --带符号整型,低字节在前,高字节在后,缩小 10 倍为实际数值,单位: m3 for (int i = 56 + multiplier; i <= 63 + multiplier; i++) { _positiveFlow.Append(message[i]); } //int positiveFlow = int.Parse(hexStr2Str(interconvert(56 + multiplier, 63 + multiplier, _positiveFlow.ToString()))) / 10;//??? var positiveFlow = float.Parse(/*hexStr2Str*/(interconvert(56 + multiplier, 63 + multiplier, _positiveFlow.ToString()))) / 10; //Console.WriteLine("正累积流量:" + positiveFlow + "m3"); StringBuilder loseFlow = new StringBuilder("");//负累积流量 --BCD 码,缩小10 倍为实际数值,单位:m³ for (int i = 64 + multiplier; i <= 71 + multiplier; i++) { loseFlow.Append(message[i]); } var _loseFlow = float.Parse(loseFlow.ToString()) / 10; //Console.WriteLine("负累积流量:" + _loseFlow + "m3"); StringBuilder loseRunTime = new StringBuilder("");//负累积运行时间 --BCD 码,单位: h。 for (int i = 72 + multiplier; i <= 79 + multiplier; i++) { loseRunTime.Append(message[i]); } var _loseRunTime = int.Parse(loseRunTime.ToString()); //Console.WriteLine("负累积运行时间:" + _loseRunTime + "h"); StringBuilder waterTemperature = new StringBuilder("");//水温 --浮点型,单位: ℃ for (int i = 80 + multiplier; i <= 87 + multiplier; i++) { waterTemperature.Append(message[i]); } var _waterTemperature = byteToFloat(waterTemperature.ToString());//??? //Console.WriteLine("水温:" + _waterTemperature + "℃"); StringBuilder _RunTime = new StringBuilder("");//累积运行时间 --带符号整型,低字节在前,高字节在后,单位: h for (int i = 88 + multiplier; i <= 95 + multiplier; i++) { _RunTime.Append(message[i]); } var RunTime = int.Parse(/*hexStr2Str*/(interconvert(88 + multiplier, 95 + multiplier, _RunTime.ToString())));//??? //Console.WriteLine("累积运行时间:" + RunTime + "h"); StringBuilder _cellVoltage = new StringBuilder("");//电池电压 --浮点型,低字节在前,高字节在后,单位: v。 for (int i = 96 + multiplier; i <= 103 + multiplier; i++) { _cellVoltage.Append(message[i]); } //float cellVoltage = float.Parse(hexStr2Str(interconvert(96 + multiplier, 103 + multiplier, _cellVoltage.ToString())));//??? float cellVoltage = byteToFloat(_cellVoltage.ToString()); //Console.WriteLine("电池电压:" + cellVoltage + "v"); StringBuilder _pipeSize = new StringBuilder("");//管径 --浮点型,单位: mm for (int i = 104 + multiplier; i <= 111 + multiplier; i++) { _pipeSize.Append(message[i]); } //float pipeSize = float.Parse(_pipeSize.ToString());//??? float pipeSize = byteToFloat(_pipeSize.ToString()); //Console.WriteLine("管径:" + pipeSize + "mm"); StringBuilder capacity = new StringBuilder("");//量程 --长整型,单位:单位缺失。 for (int i = 112 + multiplier; i <= 119 + multiplier; i++) { capacity.Append(message[i]); } //Console.WriteLine("量程:" + interconvert(0, 0, capacity.ToString()));//??? StringBuilder dampingFactor = new StringBuilder("");//阻尼系数 --ASCII 码 for (int i = 120 + multiplier; i <= 121 + multiplier; i++) { dampingFactor.Append(message[i]); } //Console.WriteLine("阻尼系数:" + hexToASCII(dampingFactor.ToString())); StringBuilder InstrumentType = new StringBuilder("");//仪表类型 for (int i = 122 + multiplier; i <= 123 + multiplier; i++) { InstrumentType.Append(message[i]); } StringBuilder diagnose = new StringBuilder("");//诊断代码(仪表故障码) --当设备上报 0x06 故障时,不应再上报其他故障。 for (int i = 124 + multiplier; i <= 125 + multiplier; i++) { diagnose.Append(message[i]); } //typeMalfunction(diagnose); //CRC校验 StringBuilder builder = new StringBuilder(""); for (int i = 128 + multiplier; i <= 129 + multiplier; i++) { builder.Append(message[i]); } if (binAccumulation(4 + multiplier, 127 + multiplier, message).ToUpper() != builder.ToString().ToUpper()) { Console.WriteLine("接收数据校验失败" + ": " + message); log.Info("登录帧校验失败" + ": " + message); Isgo(message, baseNum); return; } shareAnalysis(message, multiplier); if (validity.ToString() == "26") { Console.WriteLine("抄表数据有效"); } else { Console.WriteLine("抄表数据无效"); } Console.WriteLine("版本号:" + int.Parse(versionNum.ToString())); Console.WriteLine("瞬时流量" + byteToFloat(instantaneousFlow.ToString()) / 1000 + "m3/h"); Console.WriteLine("正累积流量:" + positiveFlow + "m3"); Console.WriteLine("负累积流量:" + _loseFlow + "m3"); Console.WriteLine("负累积运行时间:" + _loseRunTime + "h"); Console.WriteLine("水温:" + _waterTemperature + "℃"); Console.WriteLine("累积运行时间:" + RunTime + "h"); Console.WriteLine("电池电压:" + cellVoltage + "v"); Console.WriteLine("管径:" + pipeSize + "mm"); Console.WriteLine("量程:" + interconvert(0, 0, capacity.ToString()));//??? //Console.WriteLine("阻尼系数:" + hexToASCII(dampingFactor.ToString())); typeMalfunction(diagnose); //数据校验 --版本号-故障代码 Console.WriteLine("数据校验:" + binAccumulation(46 + multiplier, 125 + multiplier, message));//版本号--故障码 Console.WriteLine("校验位CS:" + binAccumulation(4 + multiplier, 127 + multiplier, message));//数据部长度--数据校验 Isgo(message, baseNum); } /// /// 表型84 /// /// /// 基数【前置位设备数据总数和】 public static void phenotype84(string message, int baseNum) { int multiplier; if (baseNum != 0) { //var multiplier = (whatFrame - 1) * 64; multiplier = baseNum; baseNum += (64 + 16); } else { multiplier = 0; baseNum = (64 + 16); } //shareAnalysis(message, multiplier); StringBuilder validity = new StringBuilder("");//抄表数据有效 --无符号整型,0x26 有效,其他无效 for (int i = 44 + multiplier; i <= 45 + multiplier; i++) { validity.Append(message[i]); } //if (validity.ToString() == "26") //{ // Console.WriteLine("抄表数据有效"); //} //else //{ // Console.WriteLine("抄表数据无效"); //} StringBuilder signDelivery = new StringBuilder("");//瞬时流量正负值 --无符号整型,0x00 代表正,0x0a 代表负 for (int i = 46 + multiplier; i <= 47 + multiplier; i++) { signDelivery.Append(message[i]); } //if (signDelivery.ToString() == "00") //{ // signDelivery.Clear().Append(""); // Console.WriteLine("瞬时流量为正值"); //} //else //{ // signDelivery.Clear().Append("-"); // Console.WriteLine("瞬时流量为负值"); //} StringBuilder instantaneousFlow = new StringBuilder(""); //瞬时流量 --缩小 1000 倍为实际值,单位: m3/h for (int i = 48 + multiplier; i <= 55 + multiplier; i++) { instantaneousFlow.Append(message[i]); } var _instantaneousFlow = float.Parse(instantaneousFlow.ToString()) / 1000; //Console.WriteLine("瞬时流量:" + signDelivery + _instantaneousFlow + "m3/h"); StringBuilder loseFlow = new StringBuilder("");//负累积流量 --缩小 10 倍为实际数值,单位: m3 for (int i = 56 + multiplier; i <= 63 + multiplier; i++) { loseFlow.Append(message[i]); } var _loseFlow = float.Parse(loseFlow.ToString()) / 10; //Console.WriteLine("负累积流量:" + signDelivery + _loseFlow + "m3"); StringBuilder loseRunTime = new StringBuilder("");//负累积运行时间 --单位: h for (int i = 64 + multiplier; i <= 71 + multiplier; i++) { loseRunTime.Append(message[i]); } var _loseRunTime = int.Parse(loseRunTime.ToString()); //Console.WriteLine("负累积运行时间:" + _loseRunTime + "h"); StringBuilder positiveFlow = new StringBuilder("");//正累积流量 --缩小 10 倍为实际数值,单位: m3 for (int i = 72 + multiplier; i <= 79 + multiplier; i++) { positiveFlow.Append(message[i]); } var _positiveFlow = float.Parse(positiveFlow.ToString()) / 10; //Console.WriteLine("正累积流量:" + _positiveFlow + "m3"); StringBuilder positiveRunTime = new StringBuilder("");//正累积运行时间 --单位: h for (int i = 80 + multiplier; i <= 87 + multiplier; i++) { positiveRunTime.Append(message[i]); } var _positiveRunTime = int.Parse(positiveRunTime.ToString()); //Console.WriteLine("正累积运行时间:" + _positiveRunTime + "h"); StringBuilder waterTemperature = new StringBuilder("");//水温 --缩小 100 倍为实际数值,单位: ℃ for (int i = 88 + multiplier; i <= 95 + multiplier; i++) { waterTemperature.Append(message[i]); } var _waterTemperature = float.Parse(waterTemperature.ToString()) / 100; //Console.WriteLine("水温:" + _waterTemperature + "℃"); StringBuilder pressure = new StringBuilder("");//压力 --缩小 1000 倍为实际数值,单位: mpa for (int i = 96 + multiplier; i <= 103 + multiplier; i++) { pressure.Append(message[i]); } var _pressure = float.Parse(pressure.ToString()) / 1000; //Console.WriteLine("压力:" + _pressure + "mpa"); StringBuilder diagnose = new StringBuilder("");//诊断代码(仪表故障码) --当设备上报 0x06 故障时,不应再上报其他故障。 for (int i = 104 + multiplier; i <= 105 + multiplier; i++) { diagnose.Append(message[i]); } //typeMalfunction(diagnose); //CRC校验 StringBuilder builder = new StringBuilder(""); for (int i = 108 + multiplier; i <= 109 + multiplier; i++) { builder.Append(message[i]); } if (binAccumulation(4 + multiplier, 107 + multiplier, message).ToUpper() != builder.ToString().ToUpper()) { Console.WriteLine("接收数据校验失败" + ": " + message); log.Info("登录帧校验失败" + ": " + message); Isgo(message, baseNum); return; } shareAnalysis(message, multiplier); if (validity.ToString() == "26") { Console.WriteLine("抄表数据有效"); } else { Console.WriteLine("抄表数据无效"); } if (signDelivery.ToString() == "00") { signDelivery.Clear().Append(""); Console.WriteLine("瞬时流量为正值"); } else { signDelivery.Clear().Append("-"); Console.WriteLine("瞬时流量为负值"); } Console.WriteLine("瞬时流量:" + signDelivery + _instantaneousFlow + "m3/h"); Console.WriteLine("负累积流量:" + signDelivery + _loseFlow + "m3"); Console.WriteLine("负累积运行时间:" + _loseRunTime + "h"); Console.WriteLine("正累积流量:" + _positiveFlow + "m3"); Console.WriteLine("正累积运行时间:" + _positiveRunTime + "h"); Console.WriteLine("水温:" + _waterTemperature + "℃"); Console.WriteLine("压力:" + _pressure + "mpa"); typeMalfunction(diagnose); //数据校验 --瞬时流量符号-故障代码 Console.WriteLine("数据校验:" + binAccumulation(46 + multiplier, 105 + multiplier, message));//版本号--故障码 Console.WriteLine("校验位CS:" + binAccumulation(4 + multiplier, 107 + multiplier, message));//数据部长度--数据校验 Isgo(message, baseNum); } /// /// 判断功能码类型 /// /// 功能码 /// /// 基数【前置位设备数据总数和】 public static void JudgmentFunctionCode(string str, string message, int baseNum) { switch ((TypeFunctionCode)int.Parse(str)) { case TypeFunctionCode.登录帧: LoginFrameAnalysis(message, ipEnd, socket); break; case TypeFunctionCode.数据帧1: dataFramesAnalysis(message, str, baseNum); break; case TypeFunctionCode.校时命令: clockAnalysis(message, ipEnd); break; default: Console.WriteLine("无此功能码: " + str); break; } } /// /// 报文结构类型 /// public enum type { 起始位, 数据部长度, 客户端地址,//12位正常,11位末加F 功能码,//00 成功,01 错误 有效负载, 校验位, 截止位 }; public enum TypeFunctionCode { 登录帧 = 1, 数据帧1 = 8, 校时命令 = 5, 默认 = 99 } /// /// 工作模式为枚举型,取值范围 0x00 定时开机,0x01 实时在线 /// public enum TypeworkPattern { 定时开机 = 0, 实时在线 } /// /// 判断表型 /// /// public static string typePheno(StringBuilder phenotype) { StringBuilder s = new StringBuilder(""); switch (phenotype.ToString()) { //--0x81 SCL-61D5/6 单向不锈钢带温度流量计 SCL61D6 单向不锈钢带温度流量计 //--0x83 SCL-61D5/6 双向不锈钢带温度流量计 SCL61D6 双向不锈钢带温度流量计 //--0x84 SCL-61D5/6 不锈钢带压力 SCL61D6 不锈钢带压力 case "81": s.Append("SCL61D6 单向不锈钢带温度流量计"); Console.WriteLine("表型:" + s); s.Clear().Append("81"); break; case "83": s.Append("SCL61D6 双向不锈钢带温度流量计"); Console.WriteLine("表型:" + s); s.Clear().Append("83"); break; case "84": s.Append("SCL61D6 不锈钢带压力"); Console.WriteLine("表型:" + s); s.Clear().Append("84"); break; default: Console.WriteLine($"无此表型: {phenotype}"); break; } return s.ToString().Trim(); } /// /// 判断报警码**只在使用08 码上报数据时才会存在 /// /// public static void typeAlarmcode(StringBuilder alarmCode) { switch (alarmCode.ToString()) { case "01": alarmCode.Clear().Append("正向流量超上限"); Console.WriteLine("报警码:" + alarmCode); break; case "02": alarmCode.Clear().Append("正向流量超下限"); Console.WriteLine("报警码:" + alarmCode); break; case "04": alarmCode.Clear().Append("负向流量超上限"); Console.WriteLine("报警码:" + alarmCode); break; case "08": alarmCode.Clear().Append("负向流量超下限"); Console.WriteLine("报警码:" + alarmCode); break; case "10": alarmCode.Clear().Append("压力超上限"); Console.WriteLine("报警码:" + alarmCode); break; case "20": alarmCode.Clear().Append("压力超下限"); Console.WriteLine("报警码:" + alarmCode); break; case "40": alarmCode.Clear().Append("预留"); Console.WriteLine("报警码:" + alarmCode); break; case "80": alarmCode.Clear().Append("预留"); Console.WriteLine("报警码:" + alarmCode); break; default: Console.WriteLine($"无此报警码: {alarmCode}"); break; } } /// /// 判断故障码**当设备上报 0x06 故障时,不应再上报其他故障。 /// /// public static void typeMalfunction(StringBuilder diagnose) { switch (diagnose.ToString()) { case "01": diagnose.Clear().Append("池电压低于3.37V,需要更换电池"); Console.WriteLine("故障码:" + diagnose); break; case "02": diagnose.Clear().Append("空管或者换能器故障无测量信号"); Console.WriteLine("故障码:" + diagnose); break; case "03": diagnose.Clear().Append("代码01 和代码02 同时发生"); Console.WriteLine("故障码:" + diagnose); break; case "04": diagnose.Clear().Append("电池电压低于3.3V,必须更换电池"); Console.WriteLine("故障码:" + diagnose); break; case "05": diagnose.Clear().Append("传感器和换能器之间通讯故障,无通讯"); Console.WriteLine("故障码:" + diagnose); break; case "06": diagnose.Clear().Append("E2PROM 损坏"); Console.WriteLine("故障码:" + diagnose); break; case "10": diagnose.Clear().Append("供水温度传感器故障(短路、开路)或供水温度低于2℃"); Console.WriteLine("故障码:" + diagnose); break; case "20": diagnose.Clear().Append("供水温度超出150℃"); Console.WriteLine("故障码:" + diagnose); break; case "40": diagnose.Clear().Append("回水温度传感器故障(短路、开路)或回水温度低于2℃"); Console.WriteLine("故障码:" + diagnose); break; case "80": diagnose.Clear().Append("回水温度超出150℃"); Console.WriteLine("故障码:" + diagnose); break; default: break; } } } }