zoukankan      html  css  js  c++  java
  • C# RFID windows 服务 网络协议方式

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

  • 相关阅读:
    hdu 5489——Removed Interval——————【删除一段区间后的LIS】
    ACdream 1431——Sum vs Product——————【dfs+剪枝】
    HDU 5496——Beauty of Sequence——————【考虑局部】
    HDU 2586——How far away ?——————【LCA模板题】
    在 Web 项目中应用 Apache Shiro
    被误解的 Node.js
    [置顶] 乔布斯的斯坦福演讲(双语)
    [置顶] 献给写作者的 Markdown 新手指南
    Linux 环境中从源代码编译安装 ReText 问题与解决
    基于 OSGi 的面向服务的组件编程
  • 原文地址:https://www.cnblogs.com/liuyunsheng/p/3739630.html
Copyright © 2011-2022 走看看