我尝试从我的 Java 串行端口读取二进制协议。我使用RXTX 库从串口读取。
该协议是用于 GPS 接收器的 SiRF 二进制协议。结构是:
- 前两个字节是 0xA0 和 0xA2,它们定义了数据帧的开始
- 接下来的两个字节是有效载荷长度 n
- 接下来的 n 个字节是有效载荷
- 最后两个字节是 0xB0 和 0xB3,它们定义了一个数据帧的结束
虽然这个结构很简单,但我无法正确读取数据。我尝试了两种不同的方法:
我写了一个线程,它从 0xA0 读取
InputStream
并将输入与 0xA0 进行比较。如果匹配,则线程读取下一个字节并与 0xA2 进行比较。如果再次匹配,它将读取接下来的两个字节并计算有效负载长度。之后,它读取长度为 n 字节的有效负载。最后,它读取最后两个字节并将它们与 0xB0 和 0xB3 进行比较。当一切都匹配时,它会从输入中创建一个十六进制字符串并将其保存到队列中。这是我的代码:try { byte[] size = new byte[2]; byte[] checkSum = new byte[2]; byte[] packet; int bytesRead = -1; while (in.available() > 0) { if (getInput() == 0xA0) { if (getInput() == 0xA2) { System.out.print("160,162,"); bytesRead = in.read(size); int payLoadLength = (size[0] << 8) | (size[1] & 0xFF); byte[] payload = new byte[payLoadLength]; bytesRead = in.read(payload); bytesRead = in.read(checkSum); if (getInput() == 0xB0) { if (getInput() == 0xB3) { System.out.println("out"); packet = new byte[2 + 2 + payLoadLength + 2 + 2]; packet[0] = (byte) START_1; packet[1] = (byte) START_2; packet[2] = size[0]; packet[3] = size[1]; for (int i = 0; i < payload.length; i++) { packet[i + 4] = payload[i]; } packet[packet.length - 4] = checkSum[0]; packet[packet.length - 3] = checkSum[1]; packet[packet.length - 2] = (byte) END_1; packet[packet.length - 1] = (byte) END_2; StringBuffer hexString = new StringBuffer(); int[] output = new int[packet.length]; for (int i = 0; i < packet.length; i++) { output[i] = 0xFF & packet[i]; hexString.append(Integer.toHexString(output[i])); } TransportMessage tm = new TransportMessage(hexString.toString()); boolean b = queue.offer(tm); System.out.println(hexString.toString().toUpperCase()); if(!b) System.err.println("TransportMessageQueue voll!"); } } else { System.out.println(); } } } } } catch (IOException e) { System.out.println(e); }
getInput()
只是从InputStream
.我使用了
SerialPortEventListener
来自 RXTX 库的。每次串行端口上发生某些事情时,都会触发 SerialPortEvent 并且我以与第一种方法类似的方式读取数据。
出于调试原因,我添加了几个System.out.println()
调用来显示线程究竟读取了什么,似乎我错过了通过InputStream
.
我现在的问题是:从 中读取这样的协议的最佳方法是什么InputStream
?在我看来,我必须让我的阅读工作与串行端口的数据同步,但我不知道如何在 Java 中做到这一点。