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

C# RFID windows 服务 网络协议方式的更多相关文章

  1. c#创建windows服务(代码方式安装、启动、停止、卸载服务)

    转载于:https://www.cnblogs.com/mq0036/p/7875864.html 一.开发环境 操作系统:Windows 10 X64 开发环境:VS2015 编程语言:C# .NE ...

  2. C# RFID windows 服务 串口方式

    话说RFID以前很火所以整理一下一年前自己处理的RFID程序,放源码. 一开始觉得他是个很神奇的东西. 包含串口通讯和网络通讯. 由于网络通讯设备太贵,所以国内的设备基本上都是在外置一个比较便宜的模块 ...

  3. Windows服务定时执行方式

    采用System.Timers.Timer 间隔固定时间执行 方式一:间隔固定的时间执行一次,关键代码: protected override void OnStart(string[] args) ...

  4. 网络协议 20 - RPC 协议(上)- 基于XML的SOAP协议

    [前五篇]系列文章传送门: 网络协议 15 - P2P 协议:小种子大学问 网络协议 16 - DNS 协议:网络世界的地址簿 网络协议 17 - HTTPDNS:私人定制的 DNS 服务 网络协议 ...

  5. 网络协议 19 - RPC协议综述:远在天边近在眼前

    [前五篇]系列文章传送门: 网络协议 14 - 流媒体协议:要说爱你不容易 网络协议 15 - P2P 协议:小种子大学问 网络协议 16 - DNS 协议:网络世界的地址簿 网络协议 17 - HT ...

  6. 玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理

    Windows服务Debug版本 注册 Services.exe -regserver 卸载 Services.exe -unregserver Windows服务Release版本 注册 Servi ...

  7. windows服务

    .net windows 服务创建.安装.卸载和调试   原文:http://www.cnblogs.com/hfliyi/archive/2012/08/12/2635290.html 我对例子做了 ...

  8. .net windows 服务创建、安装、卸载和调试

    原文:http://blog.csdn.net/angle860123/article/details/17375895 windows服务应用程序是一种长期运行在操作系统后台的程序,它对于服务器环境 ...

  9. 玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理

    原文:玩转Windows服务系列——Debug.Release版本的注册和卸载,及其原理 Windows服务Debug版本 注册 Services.exe -regserver 卸载 Services ...

随机推荐

  1. Alpha阶段第九次Scrum Meeting

    情况简述 Alpha阶段第九次Scrum Meeting 敏捷开发起始时间 2016/11/2 00:00 敏捷开发终止时间 2016/11/3 00:00 会议基本内容摘要 汇报进度,安排工作 参与 ...

  2. java如何跳出多重嵌套循环

    Java里的break能跳出循环但是只能跳出一个,goto这个在java中也只是被当作关键是,没有任何作用 要做到跳出多重嵌套循环,可以用此方法 在循环体开头设置一个标志位,设置一个标记,然后使用带此 ...

  3. TeamViewer12.0.71503(远程控制软件)精简版 单文件企业版介绍

    TeamViewer 是一款能在任何防火墙和 NAT 代理的后台用于远程控制,桌面共享和文件传输的简单且快速的解决方案.为了连接到另一台计算机,只需要在两台计算机上同时运行 TeamViewer 即可 ...

  4. jmeter测试 常用数据库的性能

    在线程组中设置线程属性,执行次数=线程数*循环次数 本次JOB共插入了5W条记录,从14:56:46开始到15:01:29结束共耗时343s,平均145.8条/s. 同理sql sever:从15:2 ...

  5. HTML颜色、超链接设置

    <html> <head> <title>显示的页面选项卡标题</title> <style type="text/css"& ...

  6. CSS选择器优先级总结

    CSS三大特性-- 继承. 优先级和层叠. 继承:即子类元素继承父类的样式; 优先级:是指不同类别样式的权重比较; 层叠:是说当数量相同时,通过层叠(后者覆盖前者)的样式. css选择符分类 首先来看 ...

  7. SQL2005解密已经被加密的存储过程

    SQL2005解密已经被加密的存储过程 第一步:打开DAC连接功能 第二步:在MASTER数据库创建一个解密存储过程 USE master GO CREATE PROCEDURE [dbo].[sp_ ...

  8. JavaScript getComputedStyle

    我们使用 element.style 也可以获取元素的CSS样式声明对象,但是其与 getComputedStyle 方法还是有一些差异的. 首先,element.style 是可读可写的,而 get ...

  9. linux下cp覆盖原so文件时引起的段错误原因确定

    原创作品,转载请注明出处http://www.cnblogs.com/leo0000/p/5694416.html 最近因为一个很有意思的段错误学习了一些新的东西. 当时现象是这样的,程序正在运行,系 ...

  10. (zz)linux awk

    博文转载自http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html 谢谢原作者.条理很清楚,由浅入深.敲了每一行命令,正确无误. ...