using System; using System.Collections; //using System.Threading.Tasks; using System.ComponentModel; using System.Net; using System.Net.Sockets; using System.Threading; namespace Mesnac.DeviceAdapter.Fuchs { public enum RecvState { //Pepperl_Fuchs 返回数据 00.06.0A.02.FF.49. //00.14.0A.02.00.4A.30.00.30.05.FB.63.AC.1F.36.81.EC.88.04.68 WaitingBeginChar1_State = 1, //等待接收帧同步字符1 0x00 WaitingBeginChar2_State = 2, //等待接收帧同步字符2 0x06 WaitingBeginChar3_State = 3, //等待接收帧同步字符3 0x01 WaitingBeginChar4_State = 4, //等待接收帧同步字符4 0x02 WaitingBeginChar5_State = 5, //等待接收帧同步字符5 0xFF WaitingBeginChar6_State = 6, //等待接收帧同步字符6 0x49 WaitingForChar7_State = 7, //等待接收帧同步字符7 0x00 }; class BgTcpClient : ICommunicateService { private Semaphore m_ReciveSem = new Semaphore(0, 100000); RecvState enumRecvState = RecvState.WaitingBeginChar1_State; int m_iPosition = 0; byte[] m_szFullMessage = new byte[1024]; //此数组用于状态机 int iBarcodeLength = 0;//条码长度 FuchsAdapter m_FuchsAdapter = 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); public AntInfo[] AntList = AntListInfo.AntList; public event RecvIdentifyData RecvIdentifyDataEvent = null; //接收线程 private void bgwReceive_DoWork(object sender, DoWorkEventArgs e) { 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) { //if(buff[0] != 0X00 && buff[1] != 0X06 && buff[2] != 0X00) //{ //LogService.Instance.Info("方法:bgwReceive_DoWork,Pepperl_Fuchs接收原始报文:" + bytesToHexStr(buff, nCount)); //} if (buff[4] == 0XFF) { Array.Clear(buff, 0, nCount); } else { m_FuchsAdapter.LogInfo.Info("方法:bgwReceive_DoWork,Pepperl_Fuchs设备:" + m_FsIP + ":" + m_FnPort + "接收原始报文:" + bytesToHexStr(buff, nCount)); PareReceiveData(buff, nCount); //调用状态机函数 } //ThreadPool.QueueUserWorkItem(new WaitCallback(PareSend_ReceiveData),buff); 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; } Thread.Sleep(10); } catch (Exception ex) { e.Cancel = true; if (m_ClientSock != null) { m_ClientSock.Close(); m_ClientSock = null; } m_FuchsAdapter.LogInfo.Info("Socket接收数据线程退出" + ex.ToString()); 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 PareSend_ReceiveData(object ReceiveData) { byte[] buffer = (byte[])ReceiveData; if (buffer[3] == 0X32) //高频连续识别返回自报数据接收 { if (m_FuchsAdapter != null) { m_FuchsAdapter.LogInfo.Info("方法:PareSend_ReceiveData,线程池1号天线发送停止指令"); m_FuchsAdapter.Device_StopIdentify(1); //处理函数 } } else if (buffer[3] == 0X34) { if (m_FuchsAdapter != null) { m_FuchsAdapter.LogInfo.Info("方法:PareSend_ReceiveData,线程池2号天线发送停止指令"); m_FuchsAdapter.Device_StopIdentify(2); //处理函数 } } else if (buffer[3] == 0X36) { if (m_FuchsAdapter != null) { m_FuchsAdapter.LogInfo.Info("方法:PareSend_ReceiveData,线程池3号天线发送停止指令"); m_FuchsAdapter.Device_StopIdentify(3); //处理函数 } } else if (buffer[3] == 0X38) { if (m_FuchsAdapter != null) { m_FuchsAdapter.LogInfo.Info("方法:PareSend_ReceiveData,线程池4号天线发送停止指令"); m_FuchsAdapter.Device_StopIdentify(4); //处理函数 } } } //发送线程(包括接收后的处理) private void bgwDeal_DoWork(object sender, DoWorkEventArgs e) { //LogService.Instance.Info("Pepperl_Fuchs 进入 bgwDeal_DoWork 线程:"); while (true) { try { m_Fsem.WaitOne(); //m_ReciveSem.WaitOne(); lock (m_FrecvData) { if (m_FrecvData.Count > 0) { byte[] buff = (byte[])m_FrecvData[0]; if (m_FuchsAdapter != null) { m_FuchsAdapter.Device_DealValidPack(buff); //处理函数 } m_FrecvData.RemoveAt(0); } } if (Exitevent.WaitOne(0, false)) { e.Cancel = true; m_FuchsAdapter.LogInfo.Info("Socket处理数据线程正常退出"); Exitevent.Reset(); return; } Thread.Sleep(10); } catch (Exception ex) { e.Cancel = true; m_FuchsAdapter.LogInfo.Info("Socket处理数据异常: " + ex.ToString()); return; } if (this.m_bgwDeal.CancellationPending) { m_FuchsAdapter.LogInfo.Info("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 //SendBuffer[iPos] = pMessagePack.m_BeginChar; //iPos += 1; //SendBuffer[iPos] = pMessagePack.m_SecondChar; //起始字符2 //iPos += 1; //SendBuffer[iPos] = pMessagePack.m_pData[pMessagePack.m_pData.Length]; //起始字符3 //iPos += Convert.ToUInt16(pMessagePack.m_pData.Length); //SendBuffer[iPos] = pMessagePack.m_Channel; //通道号 Array.Copy(pMessagePack.m_pData, 0, SendBuffer, iPos, pMessagePack.m_pData.Length); //数据域 //if (pMessagePack.m_pData[0] != 0X00 && pMessagePack.m_pData[1] != 0X16 && pMessagePack.m_pData[2] != 0X0A)//过滤日志中的心跳报文 //{ m_FuchsAdapter.LogInfo.Info("方法:SendMessage,Pepperl_Fuchs设备:" + m_FsIP + ":" + m_FnPort + "发送原始报文:" + bytesToHexStr(SendBuffer, pMessagePack.m_pData.Length)); //} int nCount = m_ClientSock.Send(SendBuffer, pMessagePack.m_pData.Length, SocketFlags.None); if (nCount > 0) //发送成功 { //LogService.Instance.Info("m_ClientSock.Send函数发送成功"); return true; } else { m_FuchsAdapter.LogInfo.Info("方法:SendMessage,连接已断开,数据发送失败"); return false; } } catch (Exception ex) { m_FuchsAdapter.LogInfo.Info("方法:SendMessage,Pepperl_Fuchs设备:" + m_FsIP + ":" + m_FnPort + "发送报文失败,请检查网络连接!"); return false; } } #region 初始化一套函数 public bool Connect() { //连接 try { Exitevent.Reset(); if (m_FsIP == "" || m_FnPort == 0) { m_FuchsAdapter.LogInfo.Info("IP和端口号不能为空,连接失败"); return false; } if (m_ClientSock != null && GetState()) { //LogService.Instance.Info("已经连接了"); 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 { //启动接收线程 m_bgwReceive.DoWork += new DoWorkEventHandler(bgwReceive_DoWork); m_bgwReceive.RunWorkerAsync(); //启动处理线程 m_bgwDeal.DoWork += new DoWorkEventHandler(bgwDeal_DoWork); m_bgwDeal.RunWorkerAsync(); return true; } catch (Exception ex) { m_FuchsAdapter.LogInfo.Info("创建后台线程异常 " + ex.ToString()); return true; } } else { return false; } } catch (Exception ex) { m_FuchsAdapter.LogInfo.Info("IP:" + m_FsIP + ",端口号:" + m_FnPort + ",Socket连接异常!"); return false; } } public bool DisConnect() { try { Exitevent.Set(); m_Fsem.Release(); Thread.Sleep(100); //if (m_bgwReceive.IsBusy) //{ // m_bgwReceive.CancelAsync(); //} //if (m_bgwDeal.IsBusy) //{ // m_bgwDeal.CancelAsync(); //} if (m_ClientSock != null) { m_ClientSock.Disconnect(false); m_ClientSock.Close(); m_ClientSock = null; } return true; } catch (Exception ex) { m_FuchsAdapter.LogInfo.Info("Socket连接异常 " + ex.ToString()); 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_FuchsAdapter = objetcter as FuchsAdapter; } #endregion //状态机函数 public void PareReceiveData(byte[] buffer, int iLen) { Array.Clear(m_szFullMessage, 0, 1024); switch (buffer[2]) { case 0X19: //高频读头开始连续识别指令 Deal_BeginIdentify(buffer, iLen); break; case 0X00: //心跳 Deal_HeartPack(buffer, iLen); break; case 0X02://高频及超高频读头停止连续识别指令 Deal_StopIdentify(buffer, iLen); break; case 0X71://超高频读头开始连续识别指令 Deal_UHFBeginIdentify(buffer, iLen); break; case 0X0A: //超高频读头单次读标签指令 Deal_UHFReadData(buffer, iLen); break; case 0X10: //高频读头单次读标签指令 Deal_HFReadData(buffer, iLen); break; case 0X05://高频读头NoData Deal_HFNoData(buffer, iLen); break; case 0X04://设置读头工作模式高频or超高频 Deal_SetAntCT(buffer, iLen); break; case 0X0D: Deal_UHFWriteData(buffer, iLen); break; case 0XBF: Deal_UHFSetSignelModel(buffer, iLen); break; default: break; } } private void Deal_UHFSetSignelModel(byte[] buffer, int iLen) { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } private void Deal_UHFWriteData(byte[] buffer, int iLen) { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } private void Deal_SetAntCT(byte[] buffer, int iLen) { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } private void Deal_HFNoData(byte[] buffer, int iLen) { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } private void Deal_HFReadData(byte[] buffer, int iLen) { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } private void Deal_UHFReadData(byte[] buffer, int iLen) { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } public void deal_TagInfo(byte Ant) { AntList[Ant - 1].ReadData = null; while (AntList[Ant - 1].IsReading) { if (AntList[Ant - 1].ReadData != null) { m_FuchsAdapter.Device_DealValidPack(AntList[Ant - 1].ReadData); Array.Clear(AntList[Ant - 1].ReadData, 0, AntList[Ant - 1].ReadData.Length); AntList[Ant - 1].IsReading = false; } } } public void Receive_tagInf(DateTime dt1, byte Ant, int timeout, bool TagInventory) { AntList[Ant - 1].ReadData = null; while (TagInventory) { int dt = (int)DateTime.Now.Subtract(dt1).TotalMilliseconds; if (AntList[Ant - 1].ReadData != null) { m_FuchsAdapter.Device_DealValidPack(AntList[Ant - 1].ReadData); Array.Clear(AntList[Ant - 1].ReadData, 0, AntList[Ant - 1].ReadData.Length); TagInventory = false; } if (dt > timeout) { //m_FuchsAdapter.DealNoData(Ant); if (!m_FuchsAdapter.Device_StopIdentify(Ant)) { m_FuchsAdapter.Device_StopIdentify(Ant); } if (AntList[Ant - 1].IsReading) { m_FuchsAdapter.LogInfo.Info("》》》Receive_tagInf:IsReading = true"); } else { m_FuchsAdapter.LogInfo.Info("》》》Receive_tagInf:IsReading = false"); } AntList[Ant - 1].IsReading = false; AntList[Ant - 1].readType = 0; TagInventory = false; } } } private void Deal_UHFBeginIdentify(byte[] buffer, int iLen) { if (buffer[4] == 0XFF) { Array.Clear(buffer, 0, iLen); m_FuchsAdapter.LogInfo.Info("丢掉数据"); } else { if (buffer[4] == 0X00) { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); m_FuchsAdapter.LogInfo.Info("接收自报数据丢进线程池,发送停止指令"); ThreadPool.QueueUserWorkItem(new WaitCallback(PareSend_UHFReceiveData), buffer); //超高频读头处理数据线程池 } else { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } } } private void PareSend_UHFReceiveData(object ReceiveData) //超高频接收数据后发送停止指令 { byte[] buffer = (byte[])ReceiveData; if (buffer[3] == 0X02) //高频连续识别返回自报数据接收 { if (m_FuchsAdapter != null) { //LogService.Instance.Info("线程池5号天线发送停止指令"); m_FuchsAdapter.Device_StopIdentify(5); //处理函数 } } else if (buffer[3] == 0X04) { if (m_FuchsAdapter != null) { //LogService.Instance.Info("线程池6号天线发送停止指令"); m_FuchsAdapter.Device_StopIdentify(6); //处理函数 } } else if (buffer[3] == 0X06) { if (m_FuchsAdapter != null) { m_FuchsAdapter.Device_StopIdentify(7); //处理函数 } } else if (buffer[3] == 0X08) { if (m_FuchsAdapter != null) { m_FuchsAdapter.Device_StopIdentify(8); //处理函数 } } } private void Deal_StopIdentify(byte[] buffer, int iLen) { if (buffer[4] == 0XFF) { Array.Clear(buffer, 0, iLen); m_FuchsAdapter.LogInfo.Info("丢掉数据"); } else { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } } private void Deal_HeartPack(byte[] buffer, int iLen) { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } private void Deal_BeginIdentify(byte[] buffer, int iLen) { if (buffer[4] == 0XFF) { Array.Clear(buffer, 0, iLen); m_FuchsAdapter.LogInfo.Info("丢掉数据"); } if (buffer[4] == 0X00) { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); //switch (buffer[3]) //{ // case 0X32: // if (AntList[0].readType > 0) // { // AntList[0].ReadData = new byte[buffer.Length]; // Array.Copy(buffer, 0, AntList[0].ReadData, 0, buffer.Length); // } // break; // case 0X34: // if (AntList[1].readType > 0) // { // AntList[1].ReadData = new byte[buffer.Length]; // Array.Copy(buffer, 0, AntList[1].ReadData, 0, buffer.Length); // } // break; // case 0X36: // if (AntList[2].readType > 0) // { // AntList[2].ReadData = new byte[buffer.Length]; // Array.Copy(buffer, 0, AntList[2].ReadData, 0, buffer.Length); // } // break; // case 0X38: // if (AntList[3].readType > 0) // { // AntList[3].ReadData = new byte[buffer.Length]; // Array.Copy(buffer, 0, AntList[3].ReadData, 0, buffer.Length); // } // break; //} m_FuchsAdapter.LogInfo.Info("接收自报数据丢进线程池,发送停止指令"); ThreadPool.QueueUserWorkItem(new WaitCallback(PareSend_ReceiveData), buffer); //超高频读头处理数据线程池 } else { Array.Copy(buffer, 0, m_szFullMessage, 0, iLen); lock (m_FrecvData) { m_FrecvData.Add(m_szFullMessage); } m_Fsem.Release(); } } //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; } } }