Java의 직렬 포트에서 이진 프로토콜을 읽으려고합니다. 나는 RXTX library을 사용하여 직렬 포트에서 읽습니다.InputStream에서 이진 프로토콜을 읽는 방법?
이 프로토콜은 GPS 수신기 용 SiRF 바이너리 프로토콜입니다. 구조는 다음
- 제 2 바이트
- 다음 2 바이트
- 다음 n 바이트가 페이로드
- 마지막에게있는 페이로드 길이 n에게되는 데이터 프레임의 시작을 정의 내지 0xA0 및 0xA2, 아르 2 바이트는 데이터 프레임의 끝을 정의하는 0xB0 및 0xB3입니다.
이 구조는 매우 간단하지만 데이터를 올바르게 읽을 수는 없습니다.
나는
InputStream
에서 읽어 내지 0xA0로 입력을 비교하는 스레드를 썼다 : 나는 두 가지 방법을 시도했다. 이 값이 일치하면 스레드는 다음 바이트를 읽고 0xA2와 비교합니다. 이 값이 다시 일치하면 다음 2 바이트를 읽고 페이로드 길이를 계산합니다. 그 후 길이가 n 바이트 인 페이로드를 읽습니다. 마침내 마지막 2 바이트를 읽고 0xB0 및 0xB3과 비교합니다. 모든 것이 일치하면 입력에서 16 진수 문자열을 만들어 대기열에 저장합니다.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가 실행되고 첫 번째 방법과 비슷한 방식으로 데이터를 읽습니다.
디버깅 이유로 나는 정확히 스레드에 의해 읽고 내가 InputStream
를 통해 발송에 실패 모든 데이터 프레임의 거의 절반을 잃었 것으로 보인다 무엇 보여 System.out.println()
여러 통화를 추가했다.
내 질문은 : InputStream
에서 그런 프로토콜을 읽는 가장 좋은 방법은 무엇입니까? 필자는 필자의 독서 노력을 시리얼 포트의 데이터와 동기화시켜야한다고 생각한다.하지만 자바에서 어떻게할지는 모른다.
이러한 작업에는 java.io.DataInputStream이 사용됩니다. –