ReaderDeviceHelper.cs读头设备管理类,通过复写SocketReceiveData虚方法编写代码解析上报数据,获取EPC标识代码,对于解析方法,如果用正则表达式应该会比较简便,但是性能没有保障,所以采用匹配byte字节方式处理,监听端口数据可以绑定多种RFID卡型号,不同型号的卡标志位可能不同,解析数据代码可以匹配多种类型卡的标志位,并获取卡号数据。
/// <summary> /// 覆写SocketHelper管理类接收数据方法,针对WYUAN读头设备处理数据 /// </summary> /// <param name="socketClient"></param> /// <param name="receiveData"></param> public override void SocketReceiveData(SocketClient socketClient, SocketReceiveData receiveData) { base.SocketReceiveData(socketClient, receiveData); Models.IOT.listen_port model_port = new BLL.IOT.listen_port().GetFirstModel("port=" + receiveData.LocalPort); if (model_port != null) { List<string> list_cardno = new List<string>(); //Socket接收到的数据(包含多条卡号数据的标志位、卡号数据、CRC-16结束数据位) byte[] receiveBytes = receiveData.ReceiveBytes; int index = 0;//接收数据检索索引值,不是单向递增1,如果与卡型匹配失败会回退起始位置重新匹配下一个卡类型标志位 int type_index = 0;//设置 while (index < receiveBytes.Length) { Entities.IOT.card_type entity = model_port.list_card_type[type_index];//设置当前匹配的卡类型 byte[] flag_bit = Utils.HexStringToByte(entity.flag_bit);//转换十六进制字符串标志位为字节数组 byte[] buffer = new byte[entity.data_length];//设置卡号字节数组缓冲区 //完整卡数据长度=标志位长度+卡号数据位长度+效验位长度 int total_length = flag_bit.Length + entity.data_length + entity.crc_length; bool ismatch = false;//是否已经成功匹配到了当前卡类型标志位 int flag_index = 0;//匹配标志位进行中的索引值 int buffer_index = 0; int end_index = 0;//上一个卡号数据匹配结束时的索引值 while (index < receiveBytes.Length) { if (ismatch) {//读取卡号数据中 buffer[buffer_index] = receiveBytes[index];//保存卡号字节数据到卡号字节数组 buffer_index++; if (buffer_index == buffer.Length) {//读取了一条完整的EPC卡号数据,进行下一条数据匹配 //保存接收到卡号数据(忽略重复卡号) string epc = Utils.ByteToHexString(buffer); if (!list_cardno.Contains(epc)) { list_cardno.Add(epc); } ismatch = false;//重新匹配下一个卡号数据 buffer_index = 0;//缓冲区索引重置为0 end_index = index;//设置上一个卡号成功匹配的结束索引值 flag_index = 0;//标志位索引设置为0 type_index = 0;//类型索引归零,重新开始匹配 } } else {//匹配标志位中 if (receiveBytes[index] == flag_bit[flag_index]) {//成功匹配标志位中,需要判断是否所有标志位都匹配成功 flag_index++; if (flag_index == flag_bit.Length) { //标志位匹配成功,开始读取卡号数据 ismatch = true; flag_index = 0; index++; continue; } } else { if (flag_index > 0) {//标志位索引值大于0,说明有部分标志匹配成功,当前标志位匹配失败 flag_index = 0;//标志位索引值设置为0,重新开始匹配标志位 } } if ((index - end_index) > total_length) {//匹配的数据长度超出单条卡数据长度 type_index++;//设置匹配下一个卡类型标志位 if (type_index < model_port.list_card_type.Count) { //后续还有卡类型需要匹配 index = end_index;//接收数据索引值重置为上一次成功匹配的结束索引 break; } else { //所有卡类型的标志位匹配失败 type_index = 0; end_index = index;//设置结束索引值为当前索引,忽略当前区段的数据 flag_index = 0;//重置标志位索引值 } } }//end if(ismatch) index++; }//end for } //分析接收数据结束,处理获取的卡号数据 ReaderReceiveData model = new ReaderReceiveData(receiveData); model.EPC = list_cardno.ToArray(); list_readerReceiveData.Add(model); } }
涉及到16进制数据格式转换,为Utils.cs类增加了相应静态方法
#region 十六进制数据格式转换操作 /// <summary> /// 字节数组转换为16进制字符串 /// </summary> /// <param name="bytes">字节数组</param> /// <param name="separator">分隔字符</param> /// <returns></returns> public static string ByteToHexString(byte[] bytes, string separator) { return BitConverter.ToString(bytes, 0).Replace("-", separator); } /// <summary> /// 字节数组转换为16进制字符串 /// </summary> /// <param name="bytes">字节数据</param> /// <returns></returns> public static string ByteToHexString(byte[] bytes) { return ByteToHexString(bytes, string.Empty); } /// <summary> /// 16进制字符串转换为字节数组 /// </summary> /// <param name="hexString">16进制字符串</param> /// <param name="separator">分隔符</param> /// <returns></returns> public static byte[] HexStringToByte(string hexString, string separator) { if (!string.IsNullOrEmpty(separator)) { //移除分隔字符 hexString = hexString.Replace(separator, ""); } if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) { returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); } return returnBytes; } /// <summary> /// 16进制字符串转换为字节数组 /// </summary> /// <param name="hexString">16进制字符串</param> /// <returns></returns> public static byte[] HexStringToByte(string hexString) { return HexStringToByte(hexString, string.Empty); } #endregion
解析数据获取到RFID卡EPC标识号后,就可以进行发卡管理了,后续可以进入业务逻辑功能代码的编写了
共有条评论 网友评论