using HighWayIot.Common; using HighWayIot.Log4net; using HighWayIot.Rfid.Dto; using MaterialTraceability.Rfid.Impl; using System; using System.Collections; using System.ComponentModel; using System.Net; using System.Net.Sockets; using System.Threading; namespace HighWayIot.Rfid.Impl { public enum RecvState { //RFly-I160 返回数据 BB DD 00 01 40 41 0D WaitingBeginChar1_State = 1, //等待接收帧同步字符1 0xBB WaitingBeginChar2_State = 2, //等待接收帧同步字符2 0xDD WaitingForBarcodeLength_State = 3, //等待条码长度不固定 WaitingForCode_State = 4, //等待指令编号Code 0x02 WaitingForStus_State = 5, //等待接受状态码 0x00 WaitingForTagCount_State = 6, //等待接受标签组数不固定 WaitingForCount_State = 7, //等待接收第一组标签读取次数 0x01 WaitingForRSSI_State = 8, //等待接收读取信号强度 0xCB WaitingForAnt_State = 9, //等待接收天线端口 0x01 WaitingForPC1_State = 10, //等待接收EPC区域 0x00 WaitingForPC2_State = 11, //等待接收EPC区域 0x00 WaitingForData_State = 12, //等待接收数据字符 WaitingForXor_State = 13, //等待比对校验位 WaitingForEndChar_State = 14, //等待接收尾字符 0x0D }; class BgTcpClient : ICommunicateService { private LogHelper log = LogHelper.Instance; private StringChange stringChange = StringChange.Instance; RecvState enumRecvState = RecvState.WaitingBeginChar1_State; int m_iPosition = 0; UInt16 m_iFullMessageLength = 0; byte m_iVerify = 0; byte[] m_szFullMessage = new byte[1024]; //此数组用于状态机 int iBarcodeGroupCount = 0; //读取的组数 int iBarcodeLength = 0;//条码长度 int iBarcodeGroupCountFlag = 0;//组数标记 RFly_I160Adapter m_RFly_I160Adapter = null; private BackgroundWorker m_bgwReceive = new BackgroundWorker(); private BackgroundWorker m_bgwDeal = new BackgroundWorker(); private string m_FsIP = ""; private Int32 m_FnPort = 0; private Socket m_ClientSock = null; private ArrayList m_FrecvData = new ArrayList(); private Semaphore m_Fsem = new Semaphore(0, 100000); private ManualResetEvent Exitevent = new ManualResetEvent(false); //接收线程 private void bgwReceive_DoWork(object sender, DoWorkEventArgs e) { //LogService.Instance.Debug("RFly-I160 进入 bgwReceive_DoWork 线程函数:"); int nPackLen = 1024; byte[] buff = new byte[nPackLen]; while (true) { try { if (m_ClientSock != null && m_ClientSock.Connected) { int nCount = m_ClientSock.Receive(buff, nPackLen, 0); if (nCount > 0) { log.RfidLog(m_FsIP + ":" + m_FnPort + " RFly-I160接收原始报文:" + bytesToHexStr(buff, nCount)); PareReceiveBufferData(buff, nCount); //调用状态机函数 continue; } else //接收错误 { if (m_ClientSock != null) { m_ClientSock.Close(); m_ClientSock = null; } e.Cancel = true; m_Fsem.Release(); } } else { e.Cancel = true; if (m_ClientSock != null) { m_ClientSock.Close(); m_ClientSock = null; } m_Fsem.Release(); return; } } catch (Exception ex) { e.Cancel = true; if (m_ClientSock != null) { m_ClientSock.Close(); m_ClientSock = null; } log.Error("Socket接收数据线程退出", ex); m_Fsem.Release(); return; } if (this.m_bgwReceive.CancellationPending) { e.Cancel = true; if (m_ClientSock != null) { m_ClientSock.Close(); m_ClientSock = null; } m_Fsem.Release(); return; } } } //发送线程(包括接收后的处理) private void bgwDeal_DoWork(object sender, DoWorkEventArgs e) { log.RfidLog("RFly-I160 进入 bgwDeal_DoWork 线程:"); while (true) { try { m_Fsem.WaitOne(); lock (m_FrecvData) { if (m_FrecvData.Count > 0) { byte[] buff = (byte[])m_FrecvData[0]; if (m_RFly_I160Adapter != null) { m_RFly_I160Adapter.Device_DealValidPack(buff); //处理函数 } m_FrecvData.RemoveAt(0); } } if (Exitevent.WaitOne(0, false)) { e.Cancel = true; log.RfidLog("Socket处理数据线程正常退出"); Exitevent.Reset(); return; } } catch (Exception ex) { e.Cancel = true; log.Error("Socket处理数据异常", ex); return; } if (this.m_bgwDeal.CancellationPending) { log.RfidLog("Socket处理数据线程异常退出"); e.Cancel = true; return; } } } //发送函数 public bool SendMessage(MessagePack pMessagePack) { UInt16 iPos = 0; byte[] u16byte = new byte[2]; try { byte[] SendBuffer = new byte[pMessagePack.m_pData.Length]; //起始字符1 Array.Copy(pMessagePack.m_pData, 0, SendBuffer, iPos, pMessagePack.m_pData.Length); //数据域 log.RfidLog(m_FsIP + ":" + m_FnPort + " RFly-I160发送原始报文:" + bytesToHexStr(SendBuffer, pMessagePack.m_pData.Length)); int nCount = m_ClientSock.Send(SendBuffer, pMessagePack.m_pData.Length, SocketFlags.None); if (nCount > 0) //发送成功 { //LogInfo.Fatal("m_ClientSock.Send函数发送成功"); return true; } else { log.RfidLog("连接已断开,数据发送失败"); return false; } } catch (Exception ex) { log.Error("发送报文异常", ex); return false; } } #region 初始化一套函数 public bool Connect() { //连接 try { Exitevent.Reset(); if (m_FsIP == "" || m_FnPort == 0) { log.RfidLog("IP和端口号不能为空,连接失败"); return false; } if (m_ClientSock != null && GetState()) { log.RfidLog("已经连接了"); return true; } m_ClientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep = new IPEndPoint(IPAddress.Parse(m_FsIP), m_FnPort); m_ClientSock.Connect(iep); if (m_ClientSock.Connected) { try { if (!m_bgwReceive.IsBusy) { //启动接收线程 m_bgwReceive.DoWork += new DoWorkEventHandler(bgwReceive_DoWork); m_bgwReceive.RunWorkerAsync(); } else { log.RfidLog("接收线程正在运行"); } //启动处理线程 if (!m_bgwDeal.IsBusy) { m_bgwDeal.DoWork += new DoWorkEventHandler(bgwDeal_DoWork); m_bgwDeal.RunWorkerAsync(); } else { log.RfidLog("处理线程正在运行"); } return true; } catch (Exception ex) { log.Error("创建后台线程异常 ", ex); return true; } } else { return false; } } catch (Exception ex) { log.Error("Socket连接异常 ", ex); return false; } } public bool DisConnect() { try { Exitevent.Set(); Thread.Sleep(100); m_Fsem.Release(); if (m_ClientSock != null) { log.Info("关闭Socket连接 "); m_ClientSock.Disconnect(false); m_ClientSock.Close(); m_ClientSock = null; } return true; } catch (Exception ex) { log.Error("Socket连接异常 ", ex); return false; } } public bool GetState() { bool bResult = false; bool blockingState = false; try { if (m_ClientSock != null) { blockingState = m_ClientSock.Blocking; byte[] tmp = new byte[1]; m_ClientSock.Blocking = false; m_ClientSock.Send(tmp, 0, 0); bResult = true; Console.WriteLine("Connected!"); } else { bResult = false; } } catch (SocketException e) { // 10035 == WSAEWOULDBLOCK if (e.NativeErrorCode.Equals(10035)) { bResult = true; Console.WriteLine("Still Connected, but the Send would block"); } else { bResult = false; Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode); } } finally { if (m_ClientSock != null) { m_ClientSock.Blocking = blockingState; } } return bResult; } public void Init(string strIp, int iPort, object objetcter) { Exitevent.Reset(); m_FsIP = strIp; m_FnPort = iPort; m_RFly_I160Adapter = objetcter as RFly_I160Adapter; } #endregion /// /// 状态机函数 /// /// /// public void PareReceiveData(byte[] buffer, int iLen) { //LogService.Instance.Debug("RFly-I160进入状态机:"); m_szFullMessage = new byte[iLen]; for (int i = 0; i < iLen; i++) { switch (enumRecvState) { case RecvState.WaitingBeginChar1_State: //开始接受数据帧1 0xBB //LogService.Instance.Debug("RFly-I160等待接收帧同步字符WaitingBeginChar1_State:0XBB"); Array.Clear(m_szFullMessage, 0, iLen);//清空为0 if (buffer[i] == 0xBB) { //LogService.Instance.Debug("Buffer数据为: " + StringChange.bytesToHexStr(buffer, buffer.Length)); m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingBeginChar2_State; } else { m_iFullMessageLength = 0; m_iPosition = 0; enumRecvState = RecvState.WaitingBeginChar1_State; } break; case RecvState.WaitingBeginChar2_State: //开始接受数据帧1 0xDD if (buffer[i] == 0xDD) { m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingForBarcodeLength_State; } else { m_iFullMessageLength = 0; m_iPosition = 0; enumRecvState = RecvState.WaitingBeginChar1_State; } break; case RecvState.WaitingForBarcodeLength_State: //开始接受数据长度(TagCount - EPC) m_szFullMessage[m_iPosition] = buffer[i]; iBarcodeLength = buffer[i]; //单组标签:18;两组标签:35 m_iPosition++; enumRecvState = RecvState.WaitingForCode_State; break; case RecvState.WaitingForCode_State: //开始接受指令编号 if (buffer[i] == 0x02) { m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingForStus_State; } else if (buffer[i] == 0x90) // 如果是心跳BB DD 01 90 00 1F 8E 0D { //LogService.Instance.Debug("RFly-I160等待接受WaitingForEndChar_State:温度"); m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingForEndChar_State; } else if (buffer[i] == 0xBF) // 如果是心跳BB DD 04 BF 00 00 00 F9 0B 49 0D { //LogService.Instance.Debug("RFly-I160等待接受WaitingForEndChar_State:心跳"); m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingForEndChar_State; } else { m_iFullMessageLength = 0; m_iPosition = 0; enumRecvState = RecvState.WaitingBeginChar1_State; } break; case RecvState.WaitingForStus_State: //开始接受状态码 if (buffer[i] == 0x00) { m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingForTagCount_State; } else if (buffer[i] == 0x40) { m_szFullMessage[m_iPosition] = buffer[i]; //LogService.Instance.Debug("RFU620等待接受WaitingForEndChar_State:Noread"); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); m_iPosition = 0; i = iLen; enumRecvState = RecvState.WaitingBeginChar1_State; //LogService.Instance.Debug("RFly-I160状态机结束。"); } break; case RecvState.WaitingForTagCount_State: //开始接受标签组数 Array.Copy(buffer, i, m_szFullMessage, m_iPosition, iBarcodeLength);//m_iPosition = 5 byte[] tempData = new byte[iBarcodeLength]; Array.Clear(tempData, 0, iBarcodeLength); Array.Copy(buffer, i, tempData, 0, iBarcodeLength); //LogService.Instance.Debug("解析的数据为: " + StringChange.bytesToHexStr(tempData, iBarcodeLength)); //m_szFullMessage[m_iPosition] = buffer[i]; //单组标签:01;两组标签:02 m_iPosition = m_iPosition + iBarcodeLength; //m_iPosition = 39 i = i + iBarcodeLength - 1; //i = 39 enumRecvState = RecvState.WaitingForXor_State; break; case RecvState.WaitingForXor_State: //开始比对校验位 Rfly160 byte[] m_CRCVerify = new byte[1024]; //此数组用于校验位计算 Array.Clear(m_CRCVerify, 0, m_CRCVerify.Length); Array.Copy(m_szFullMessage, 2, m_CRCVerify, 0, iBarcodeLength + 3); //校验位计算是从Length - EPC 结束 m_szFullMessage[m_iPosition] = buffer[i]; m_iVerify = m_szFullMessage[m_iPosition]; if (m_iVerify == CalculateVerify(m_CRCVerify, m_CRCVerify.Length)) { m_iPosition++; enumRecvState = RecvState.WaitingForEndChar_State; } else //如果校验不成功 { m_iFullMessageLength = 0; m_iPosition = 0; enumRecvState = RecvState.WaitingBeginChar1_State; } break; case RecvState.WaitingForEndChar_State: if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x00 && buffer[3] != 0x90) //此处为Noread数据显示 { //LogService.Instance.Debug("RFly-I160等待接受WaitingForEndChar_State:Noread"); m_szFullMessage[0] = 0xBB; m_szFullMessage[1] = 0xDD; m_szFullMessage[2] = 0x00; lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); m_iPosition = 0; i = iLen; enumRecvState = RecvState.WaitingBeginChar1_State; } //else if (buffer[i] == 0x00) //获取温度 //{ // m_szFullMessage[3] = 0x00; // m_iPosition++; // lock (m_FrecvData) // { // m_FrecvData.Add(m_szFullMessage); // } // m_Fsem.Release(); //} else if (buffer[i] == 0x00) //获取温度 { //m_szFullMessage[3] = 0x90; //m_iPosition++; Array.Copy(buffer, 0, m_szFullMessage, 0, 8); i = 8; lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); //add by wenjy 2022-09-03 //m_iPosition = 0; //i = iLen; //enumRecvState = RecvState.WaitingBeginChar1_State; } else if (buffer[i] == 0x11) { //m_szFullMessage[3] = 0x00; Array.Copy(buffer, 0, m_szFullMessage, 0, 7); i = 7; lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } else if (buffer[i] == 0x01) { //m_szFullMessage[3] = 0x00; Array.Copy(buffer, 0, m_szFullMessage, 0, 8); i = 8; lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } else if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x04 && buffer[3] == 0xBF) { m_szFullMessage[3] = 0xBF; m_iPosition++; lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } else { m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; if (buffer[i] == 0x0D) { //LogService.Instance.Debug("RFly-I160准备发送"); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } } m_iPosition = 0; enumRecvState = RecvState.WaitingBeginChar1_State; //LogService.Instance.Debug("RFly-I160状态机结束。"); break; } } } /// /// 状态机函数 Add By WenJy 2022-09-26 /// /// /// public void PareReceiveBufferData(byte[] buffer, int iLen) { var bufferStr = stringChange.bytesToHexStr(buffer, iLen); log.RfidLog(String.Format("进入状态机函数:{0}", bufferStr)); m_szFullMessage = new byte[iLen]; for (int i = 0; i < iLen; i++) { switch (enumRecvState) { case RecvState.WaitingBeginChar1_State: //开始接受数据帧1 0xBB Array.Clear(m_szFullMessage, 0, iLen);//清空为0 if (buffer[i] == 0xBB) { m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingBeginChar2_State; } else { m_iFullMessageLength = 0; m_iPosition = 0; enumRecvState = RecvState.WaitingBeginChar1_State; } break; case RecvState.WaitingBeginChar2_State: //开始接受数据帧1 0xDD if (buffer[i] == 0xDD) { m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingForBarcodeLength_State; } else { m_iFullMessageLength = 0; m_iPosition = 0; enumRecvState = RecvState.WaitingBeginChar1_State; } break; case RecvState.WaitingForBarcodeLength_State: //开始接受数据长度(TagCount - EPC) m_szFullMessage[m_iPosition] = buffer[i]; iBarcodeLength = buffer[i]; //单组标签:18;两组标签:35 m_iPosition++; enumRecvState = RecvState.WaitingForCode_State; break; case RecvState.WaitingForCode_State: //开始接受指令编号 if (buffer[i] == 0x02) { m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingForStus_State; } else if (buffer[i] == 0x90) // 如果是心跳BB DD 01 90 00 1F 8E 0D { //LogService.Instance.Debug("RFly-I160等待接受WaitingForEndChar_State:温度"); m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingForEndChar_State; } else if (buffer[i] == 0xBF) // 如果是心跳BB DD 04 BF 00 00 00 F9 0B 49 0D { //LogService.Instance.Debug("RFly-I160等待接受WaitingForEndChar_State:心跳"); m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingForEndChar_State; } else { m_iFullMessageLength = 0; m_iPosition = 0; enumRecvState = RecvState.WaitingBeginChar1_State; } break; case RecvState.WaitingForStus_State: //开始接受状态码 if (buffer[i] == 0x00) { m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; enumRecvState = RecvState.WaitingForTagCount_State; } else if (buffer[i] == 0x40) { m_szFullMessage[m_iPosition] = buffer[i]; //LogService.Instance.Debug("RFU620等待接受WaitingForEndChar_State:Noread"); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); m_iPosition = 0; i = iLen; enumRecvState = RecvState.WaitingBeginChar1_State; //LogService.Instance.Debug("RFly-I160状态机结束。"); } break; case RecvState.WaitingForTagCount_State: //开始接受标签组数 Array.Copy(buffer, i, m_szFullMessage, m_iPosition, iBarcodeLength);//m_iPosition = 5 byte[] tempData = new byte[iBarcodeLength]; Array.Clear(tempData, 0, iBarcodeLength); Array.Copy(buffer, i, tempData, 0, iBarcodeLength); m_iPosition = m_iPosition + iBarcodeLength; //m_iPosition = 39 i = i + iBarcodeLength - 1; //i = 39 enumRecvState = RecvState.WaitingForXor_State; break; case RecvState.WaitingForXor_State: //开始比对校验位 Rfly160 byte[] m_CRCVerify = new byte[1024]; //此数组用于校验位计算 Array.Clear(m_CRCVerify, 0, m_CRCVerify.Length); Array.Copy(m_szFullMessage, 2, m_CRCVerify, 0, iBarcodeLength + 3); //校验位计算是从Length - EPC 结束 m_szFullMessage[m_iPosition] = buffer[i]; m_iVerify = m_szFullMessage[m_iPosition]; if (m_iVerify == CalculateVerify(m_CRCVerify, m_CRCVerify.Length)) { m_iPosition++; enumRecvState = RecvState.WaitingForEndChar_State; } else //如果校验不成功 { m_iFullMessageLength = 0; m_iPosition = 0; enumRecvState = RecvState.WaitingBeginChar1_State; } break; case RecvState.WaitingForEndChar_State: if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x00 && buffer[3] != 0x90) //此处为Noread数据显示 { m_szFullMessage[0] = 0xBB; m_szFullMessage[1] = 0xDD; m_szFullMessage[2] = 0x00; lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); m_iPosition = 0; i = iLen; enumRecvState = RecvState.WaitingBeginChar1_State; } else if (buffer[0] == 0xBB && buffer[1] == 0xDD && buffer[2] == 0x04 && buffer[3] == 0xBF) { Array.Copy(buffer, 0, m_szFullMessage, 0, 11); i = 11; lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); i = iLen; } else if (buffer[i] == 0x00) //获取温度 { Array.Copy(buffer, 0, m_szFullMessage, 0, 8); i = 8; lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); i = iLen; } else if (buffer[i] == 0x11) { Array.Copy(buffer, 0, m_szFullMessage, 0, 7); i = 7; lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } else if (buffer[i] == 0x01) { Array.Copy(buffer, 0, m_szFullMessage, 0, 8); i = 8; lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } else { m_szFullMessage[m_iPosition] = buffer[i]; m_iPosition++; if (buffer[i] == 0x0D) { lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } } m_iPosition = 0; enumRecvState = RecvState.WaitingBeginChar1_State; break; } } } //CRC异或校验 public byte CalculateVerify(byte[] pMessage, int iLength) { UInt16 i; byte iVerify = 0; iVerify = pMessage[0]; for (i = 1; i < iLength; i++) { iVerify = (byte)(iVerify ^ pMessage[i]); } return iVerify; } private byte[] Swap16Bytes(byte[] OldU16) { byte[] ReturnBytes = new byte[2]; ReturnBytes[1] = OldU16[0]; ReturnBytes[0] = OldU16[1]; return ReturnBytes; } private string bytesToHexStr(byte[] bytes, int iLen)//e.g. { 0x01, 0x01} ---> " 01 01" { string returnStr = ""; if (bytes != null) { for (int i = 0; i < iLen; i++) { returnStr += bytes[i].ToString("X2"); } } return returnStr; } } }