|
|
|
|
@ -0,0 +1,231 @@
|
|
|
|
|
package com.zhehekeji.web.service.RFID;
|
|
|
|
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
|
import java.io.OutputStream;
|
|
|
|
|
import java.net.Socket;
|
|
|
|
|
import java.net.SocketTimeoutException;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.HashSet;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class RFIDTCPClient {
|
|
|
|
|
|
|
|
|
|
private Socket socket;
|
|
|
|
|
private OutputStream outputStream;
|
|
|
|
|
private InputStream inputStream;
|
|
|
|
|
private String host;
|
|
|
|
|
private int port;
|
|
|
|
|
|
|
|
|
|
public RFIDTCPClient(String host, int port) {
|
|
|
|
|
this.host = host;
|
|
|
|
|
this.port = port;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean connect() {
|
|
|
|
|
try {
|
|
|
|
|
socket = new Socket(host, port);
|
|
|
|
|
socket.setSoTimeout(200);
|
|
|
|
|
outputStream = socket.getOutputStream();
|
|
|
|
|
inputStream = socket.getInputStream();
|
|
|
|
|
return true;
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void disconnect() {
|
|
|
|
|
try {
|
|
|
|
|
if (outputStream != null) {
|
|
|
|
|
outputStream.close();
|
|
|
|
|
}
|
|
|
|
|
if (inputStream != null) {
|
|
|
|
|
inputStream.close();
|
|
|
|
|
}
|
|
|
|
|
if (socket != null) {
|
|
|
|
|
socket.close();
|
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void sendHexCommand(String hexCommand) throws IOException {
|
|
|
|
|
byte[] bytes = hexStringToByteArray(hexCommand);
|
|
|
|
|
outputStream.write(bytes);
|
|
|
|
|
outputStream.flush();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Set<RFIDData> receiveRFIDData() throws IOException {
|
|
|
|
|
Set<RFIDData> dataSet = new HashSet<>();
|
|
|
|
|
|
|
|
|
|
// 创建一个缓冲区来存储接收到的数据
|
|
|
|
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
|
|
|
|
|
|
|
|
|
// 设置一个超时机制,避免无限等待
|
|
|
|
|
// 先读取一批数据到缓冲区
|
|
|
|
|
byte[] tempBuffer = new byte[1024];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
int bytesRead;
|
|
|
|
|
while ((bytesRead = inputStream.read(tempBuffer)) != -1) {
|
|
|
|
|
buffer.write(tempBuffer, 0, bytesRead); // 记录读取的数据到日志
|
|
|
|
|
log.info("读取到 {} 字节数据: {}", bytesRead, bytesToHex(Arrays.copyOfRange(tempBuffer, 0, bytesRead)));
|
|
|
|
|
|
|
|
|
|
// 如果读取到足够数据就停止
|
|
|
|
|
if (buffer.size() > 4096) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
log.info("总共读取到 {} 字节数据", buffer.size());
|
|
|
|
|
} catch (SocketTimeoutException e) {
|
|
|
|
|
// 超时正常,继续处理已接收的数据
|
|
|
|
|
log.info("读取数据超时,继续处理已接收的数据");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理缓冲区中的数据
|
|
|
|
|
byte[] receivedData = buffer.toByteArray();
|
|
|
|
|
int position = 0;
|
|
|
|
|
|
|
|
|
|
// 循环查找并解析所有以A0开头的数据包
|
|
|
|
|
while (position < receivedData.length - 2) {
|
|
|
|
|
// 查找A0起始字节
|
|
|
|
|
if (receivedData[position] == (byte) 0xA0) {
|
|
|
|
|
// 确保有足够的数据读取长度字节
|
|
|
|
|
if (position + 1 >= receivedData.length) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 读取长度
|
|
|
|
|
int length = receivedData[position + 1] & 0xFF;
|
|
|
|
|
|
|
|
|
|
// 确保有足够的数据
|
|
|
|
|
if (position + 2 + length > receivedData.length) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 提取数据部分
|
|
|
|
|
byte[] data = Arrays.copyOfRange(receivedData, position + 2, position + 2 + length);
|
|
|
|
|
|
|
|
|
|
// 解析数据
|
|
|
|
|
RFIDData rfidData = parseRFIDData(data);
|
|
|
|
|
if (rfidData != null) {
|
|
|
|
|
dataSet.add(rfidData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移动到下一个数据包
|
|
|
|
|
position += 2 + length;
|
|
|
|
|
} else {
|
|
|
|
|
// 移动到下一个字节
|
|
|
|
|
position++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dataSet;
|
|
|
|
|
}
|
|
|
|
|
private RFIDData parseRFIDData(byte[] data) {
|
|
|
|
|
try {
|
|
|
|
|
// 检查数据长度是否足够
|
|
|
|
|
if (data.length < 21) { // 至少需要21个字节
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查固定值是否正确
|
|
|
|
|
if((data[1] & 0xFF) != 0X81){
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 0x01 是固定值 (data[0])
|
|
|
|
|
// 81 00 0C 1C 是其他数据 (data[1]-data[4])
|
|
|
|
|
// 接下来2个字节是PC值 (data[5], data[6])
|
|
|
|
|
String pc = bytesToHex(Arrays.copyOfRange(data, 5, 7));
|
|
|
|
|
|
|
|
|
|
// 接下来12个字节是EPC值 (data[7] 到 data[18])
|
|
|
|
|
String epc = bytesToHex(Arrays.copyOfRange(data, 7, 19));
|
|
|
|
|
|
|
|
|
|
// 接下来2个字节是CRC值 (data[19], data[20])
|
|
|
|
|
String crc = bytesToHex(Arrays.copyOfRange(data, 19, 21));
|
|
|
|
|
|
|
|
|
|
// 剩余字节是TID值 (data[21] 到 data[33],共12个字节)
|
|
|
|
|
// 确保不会越界
|
|
|
|
|
int tidStart = 21;
|
|
|
|
|
int tidEnd = tidStart + 12; // TID固定为12个字节
|
|
|
|
|
if (tidEnd <= data.length) {
|
|
|
|
|
String tid = bytesToHex(Arrays.copyOfRange(data, tidStart, tidEnd));
|
|
|
|
|
RFIDData rfidData = new RFIDData(pc, epc, crc, tid);
|
|
|
|
|
log.info("rfidData:{}", rfidData);
|
|
|
|
|
return rfidData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果没有TID数据,创建一个空的TID
|
|
|
|
|
RFIDData rfidData = new RFIDData(pc, epc, crc, "");
|
|
|
|
|
log.info("rfidData:{}", rfidData);
|
|
|
|
|
return rfidData;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("解析RFID数据时出错: ", e);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private byte[] hexStringToByteArray(String hex) {
|
|
|
|
|
hex = hex.replaceAll(" ", ""); // 移除空格
|
|
|
|
|
int len = hex.length();
|
|
|
|
|
byte[] data = new byte[len / 2];
|
|
|
|
|
for (int i = 0; i < len; i += 2) {
|
|
|
|
|
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
|
|
|
|
|
+ Character.digit(hex.charAt(i+1), 16));
|
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String bytesToHex(byte[] bytes) {
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
for (byte b : bytes) {
|
|
|
|
|
sb.append(String.format("%02X", b));
|
|
|
|
|
}
|
|
|
|
|
return sb.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Set<String> checkTid(String ip ,int port){
|
|
|
|
|
RFIDTCPClient client = new RFIDTCPClient(ip, port);
|
|
|
|
|
|
|
|
|
|
Set<RFIDData> data = new HashSet<>();
|
|
|
|
|
if (client.connect()) {
|
|
|
|
|
try {
|
|
|
|
|
for (int i = 0; i < 8; i++){
|
|
|
|
|
if (i%2==0)
|
|
|
|
|
client.sendHexCommand("A0 04 01 74 01 E6");
|
|
|
|
|
else
|
|
|
|
|
client.sendHexCommand("A0 04 01 74 00 E7");
|
|
|
|
|
|
|
|
|
|
client.sendHexCommand("A0 0A FF 81 02 00 06 00 00 00 00 CE");
|
|
|
|
|
|
|
|
|
|
data.addAll(client.receiveRFIDData());
|
|
|
|
|
}
|
|
|
|
|
if (data != null) {
|
|
|
|
|
log.info("接收到RFID数据: " + data.toString());
|
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
} finally {
|
|
|
|
|
client.disconnect();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
System.out.println("连接失败");
|
|
|
|
|
}
|
|
|
|
|
Set<String> setData = data.stream().map(RFIDData::getTid).collect(Collectors.toSet());
|
|
|
|
|
log.info("接收到的RFID数据: " + setData);
|
|
|
|
|
return setData;
|
|
|
|
|
}
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
checkTid("127.0.0.1", 4002);
|
|
|
|
|
}
|
|
|
|
|
}
|