上篇话说是串口方式操作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简单明了想要搞个程序还是很容易的。