上篇話說是串口方式操作RFID設備。 下面介紹網絡協議方式。 設備支持斷線重連。 那我們的服務也不能差了不是。 所以這個服務類也是支持的哦。
不解釋上代碼:
namespace Rfid { /// <summary> /// 獲取Vip數據 /// </summary> /// <param name="vip"></param> public delegate void GetVipEventHandle(object obj, MarkArgs vip); /// <summary> /// 識別標簽 /// </summary> /// <param name="idMark"></param> public delegate void IdentificationMarksEventHandle(object obj, MarkArgs idMark); /// <summary> /// 寫標簽 /// </summary> public delegate void WriteMarksEventHandle(object obj, MarkArgs writeMark); public class RfidSocket { public event GetVipEventHandle GetVip; public event IdentificationMarksEventHandle IdentificationMarks; public event WriteMarksEventHandle WriteMarks; /// <summary> /// 識別標簽協議 /// </summary> public readonly byte[] MReadMarks = new byte[5] { 0xA0, 0x03, 0x82, 0x00, 0xDB }; /// <summary> /// 接受失敗協議 /// </summary> public readonly byte[] MErrorHeader = new byte[3] { 0xE4, 0x04, 0x82 }; /// <summary> /// 接受成功協議 /// </summary> public readonly byte[] MSucessHeader = new byte[3] { 0xE0, 0x10, 0x82 }; /// <summary> /// Vip數據長度 /// </summary> public const int MDataLength = 12; /// <summary> /// 發送讀取協議證 /// </summary> public System.Windows.Forms.Timer MTimer = new System.Windows.Forms.Timer(); /// <summary> /// 鏈接狀態 /// </summary> public bool Connected = false; /// <summary> /// Vip編號 /// </summary> public string VipId = string.Empty; /// <summary> /// 全局鎖 /// </summary> public object MLock = new object(); /// <summary> /// Socket通訊 /// </summary> public SocketClient Client = new SocketClient(); /// <summary> /// 連接錯誤次數 /// </summary> public int MConnectErrorCount = 0; public string Ip { get; set; } public int Port { get; set; } public int ErrorCount { get; set; } public RfidSocket(string ip, int port, int errorCount) { this.Ip = ip; this.Port = port; this.ErrorCount = errorCount; } void client_OnDisconnected(object sender) { Client.mOnConnected -= client_mOnConnected; Client.mOnError -= client_mOnError; Client.OnDataIn -= client_OnDataIn; Client.OnDisconnected -= client_OnDisconnected; } void client_OnDataIn(object sender, byte[] data) { try { GC.Collect(); GC.WaitForFullGCComplete(); GC.Collect(); //當前不考慮數據協議失敗情況 Monitor.Enter(MLock); //判斷消息頭 if (data.Length > 3) { IdentificationTag(data); WriteTag(data); } ReaderTag(data); } finally { Monitor.Exit(MLock); } } /// 識別標簽協 private void IdentificationTag(byte[] data) { //識別標簽協議成功 if (data[0] == 0xE0 && data[1] == 0x10 && data[2] == 0x82) { //解析標簽成功 if (data.Length >= 18) { var vipByte = new byte[4]; Array.Copy(data, 13, vipByte, 0, vipByte.Length); var vipId = ((vipByte[0]) + (vipByte[1] << 8) + (vipByte[2] << 16) + (vipByte[3] << 32)).ToString(); if (IdentificationMarks != null) { var markArgs = new MarkArgs(vipId, string.Empty, true); IdentificationMarks(this, markArgs); } } } else if (data[0] == 0xE4 && data[1] == 0x04 && data[2] == 0x82) { if (IdentificationMarks != null) { var markArgs = new MarkArgs(string.Empty, string.Empty, false); IdentificationMarks(this, markArgs); } } } /// 快寫標簽 private void WriteTag(byte[] data) { if (data[0] == 0xE0 && data[1] == 0x04 && data[2] == 0x9C) { if (data.Length >= 6) { if (data[4] == 0x0) { //寫標簽成功 if (WriteMarks != null) { var markArgs = new MarkArgs(string.Empty, string.Empty, true); WriteMarks(this, markArgs); } } else { //寫標簽失敗 if (WriteMarks != null) { var markArgs = new MarkArgs(string.Empty, string.Empty, false); WriteMarks(this, markArgs); } } } } } /// 定時模式讀取標簽 private void ReaderTag(byte[] data) { if (data.Length >= 17) { if (data[0] == 0x00 && data[1] == 0x00 && data[16] == 0xFF) { var bytCheck = new byte[15]; Array.Copy(data, 0, bytCheck, 0, 15); var checkSum = EPCSDKHelper.CheckSum(bytCheck) & 0xFF;//校驗和 if (data[15] == checkSum) { var vipByte = new byte[4]; Array.Copy(bytCheck, 10, vipByte, 0, 4); var vipId = ((vipByte[0]) + (vipByte[1] << 8) + (vipByte[2] << 16) + (vipByte[3] << 32)).ToString(); this.VipId = vipId; if (GetVip != null) { var markArgs = new MarkArgs(this.VipId, string.Empty, true); GetVip(this, markArgs); } } } } } private void client_mOnError(object sender, SocketException error) { if (!Client.ConnectFlag) { ReConnect(); } } private void client_mOnConnected(object sender) { MConnectErrorCount = 0; } private void ReConnect() { if (Client != null) { Client.mOnConnected -= client_mOnConnected; Client.mOnError -= client_mOnError; Client.OnDataIn -= client_OnDataIn; Client.OnDisconnected -= client_OnDisconnected; } Client = new SocketClient(); Client.Connect(this.Ip, this.Port); Client.mOnConnected += client_mOnConnected; Client.mOnError += client_mOnError; Client.OnDataIn += client_OnDataIn; Client.OnDisconnected += client_OnDisconnected; } private void mTimer_Tick(object sender, EventArgs e) { try { MTimer.Enabled = false; if (Client.ConnectFlag) { Client.Send(TagProtocol.MIdentificationMarks); } else { MConnectErrorCount++; if (MConnectErrorCount > this.ErrorCount) { ReConnect(); } } } finally { MTimer.Enabled = true; } } public void Start() { Client = new SocketClient(); Client.Connect(this.Ip, this.Port); Client.mOnConnected += client_mOnConnected; Client.mOnError += client_mOnError; Client.OnDataIn += client_OnDataIn; Client.OnDisconnected += client_OnDisconnected; MTimer.Interval = 1000; MTimer.Enabled = true; MTimer.Tick += mTimer_Tick; } public void ClearVipId() { try { Monitor.Enter(MLock); this.VipId = string.Empty; } finally { Monitor.Exit(MLock); } } public void WriteMark(int mark) { if (mark < 0 && mark > 0xffffffff) { throw new Exception("超出寫標簽范圍!"); } var markByte = mark.ToString("x").PadLeft(8, '0'); var byt = new byte[4]; for (var i = 0; i < markByte.Length; i = i + 2) { byt[i / 2] = (byte)Convert.ToInt32(markByte[i].ToString() + markByte[i + 1].ToString(), 16); } var writeMarkData = new byte[10]; Array.Copy(TagProtocol.MWriteMark, 0, writeMarkData, 0, TagProtocol.MWriteMark.Length); Array.Copy(byt, 0, writeMarkData, TagProtocol.MWriteMark.Length, byt.Length); //寫校驗和 writeMarkData[9] = (byte)(EPCSDKHelper.CheckSum(writeMarkData) & 0xFF); Client.Send(writeMarkData); GC.Collect(); GC.WaitForFullGCComplete(); GC.Collect(); } }
上面介紹了網絡通訊的設備類當然也少不了Socket通訊類。 不然沒法通許不是
namespace Rfid { public delegate void ClientErrorEvent(object sender, SocketException error); public delegate void ClientOnDataInHandler(object sender, byte[] data); public delegate void ClientEvent(object sender); public class SocketClient { public event ClientEvent mOnConnected = null; public event ClientEvent OnDisconnected = null; public event ClientOnDataInHandler OnDataIn = null; public event ClientErrorEvent mOnError = null; private Socket cli = null; private byte[] databuffer; private int buffersize = 64 * 1024; public bool ConnectFlag { get { if (cli == null) { return false; } return cli.Connected; } } private void RaiseDisconnectedEvent() { if (null != OnDisconnected) OnDisconnected(this); } private void RaiseErrorEvent(SocketException error) { if (null != mOnError) mOnError(this, error); } private void HandleConnectionData(IAsyncResult parameter) { Socket remote = (Socket)parameter.AsyncState; int read = remote.EndReceive(parameter); if (0 == read) { RaiseDisconnectedEvent(); } else { byte[] received = new byte[read]; Array.Copy(databuffer, 0, received, 0, read); if (null != OnDataIn) OnDataIn(this, received); StartWaitingForData(remote); } } private void HandleIncomingData(IAsyncResult parameter) { try { HandleConnectionData(parameter); } catch (ObjectDisposedException) { RaiseDisconnectedEvent(); } catch (SocketException x) { if (x.ErrorCode == 10054) { RaiseDisconnectedEvent(); } RaiseErrorEvent(x); } } private void StartWaitingForData(Socket soc) { soc.BeginReceive(databuffer, 0, buffersize, SocketFlags.None, new AsyncCallback(HandleIncomingData), soc); } private void HandleSendFinished(IAsyncResult parameter) { Socket socket = (Socket)parameter.AsyncState; socket.EndSend(parameter); } public SocketClient() { databuffer = new byte[buffersize]; } private void Connected(IAsyncResult iar) { Socket socket = (Socket)iar.AsyncState; try { socket.EndConnect(iar); } catch (SocketException x) { RaiseErrorEvent(x); return; } catch (ArgumentException) { return; } catch (Exception e) { LogInfo.Error("Connected:" + e.Message); LogInfo.Error(e.StackTrace); return; } if (null != mOnConnected) mOnConnected(this); StartWaitingForData(socket); } public void Connect(string ip, int port) { cli = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep = new IPEndPoint(IPAddress.Parse(ip), port); try { cli.BeginConnect(iep, new AsyncCallback(Connected), cli); } catch (SocketException er) { LogInfo.Error("與服務器無法建立連接!錯誤編號:" + er.ErrorCode + " 錯誤消息:" + er.Message); } } public void Close() { cli.Shutdown(SocketShutdown.Both); cli.Close(); } public void Send(byte[] buffer) { try { cli.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(HandleSendFinished), cli); } catch (ObjectDisposedException) { RaiseDisconnectedEvent(); } catch (SocketException x) { RaiseErrorEvent(x); } } }
看到這些你有沒有什么想說的。 提出你的想法。其實搞和硬件通訊還是很有趣的。下篇我將介紹一下讓我惡心的不能再惡心的東進的電話卡模塊。他的SDK簡直無法用言語表達了(我只能說祝福了)。 對於RFID的SDK簡單明了想要搞個程序還是很容易的。