我嘗試從我的Java串口讀取二進制協議。我使用RXTX library從串口讀取數據。如何從InputStream讀取二進制協議?
該協議是用於GPS接收機的SiRF二進制協議。結構是:
- 頭兩個字節是0XA0和0xA2,它定義一個數據幀
- 下兩個字節是有效載荷長度n
- 下一個n個字節是有效載荷
- 最後的開始兩個字節是0xB0和0xB3,它們定義了數據幀的末尾
雖然這個結構非常簡單,但我無法正確讀取數據。我嘗試兩種不同的方式:
我寫了一個線程,它從
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
一個字節。我使用了RXTX庫中的
SerialPortEventListener
。每當串口發生什麼事情時,SerialPortEvent就會被觸發,並以類似於第一種方法的方式讀取數據。
爲了調試原因,我添加了一些System.out.println()
來電顯示究竟是由線程讀取,似乎我的思念幾乎通過InputStream
sended所有數據幀的一半。
我現在的問題是:從InputStream
讀取這樣的協議的最佳方式是什麼?在我看來,我必須讓我的閱讀努力與串口數據同步,但我不知道如何在Java中做到這一點。
java.io.DataInputStream用於這些任務。 –