上篇話說是序列槽方式操作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簡單明了想要搞個程式還是很容易的。