我有一个盒子,它每 5 秒通过串行端口向我发送控制消息 #2214,但是当发生某些情况时,这个盒子会向我发送预期的消息,例如。 $22021CB47E06B9B97BA56600 我需要处理这个“美元消息”,但我需要完整的消息。当我从 java 运行代码时,框的输出看起来像
AVAILABLE 6
#2214
AVAILABLE 1
AVAILABLE 7
#2214
AVAILABLE 1
$
AVAILABLE 14
22021CB47E06B9
AVAILABLE 12
B97BA56600
AVAILABLE 4
#221
AVAILABLE 3
4
如果您不知道消息的大小,有什么方法可以等待所有字节? 我的代码中有一段。我尝试了很多方法。感谢您的帮助。
public static class SerialReader implements Runnable {
InputStream in;
SerialPort comPort;
public SerialReader(InputStream in, SerialPort comPort) {
this.in = in;
this.comPort = comPort;
}
@Override
public void run() {
comPort.addDataListener(new SerialPortDataListener() {
@Override
public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
}
@Override
public void serialEvent(SerialPortEvent event) {
try {
StringWriter sw = new StringWriter();
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
return;
}
int i = 0;
while ((i = in.available()) > 0) {
byte[] readBuffer = new byte[i];
in.read(readBuffer);
System.out.println("AVAILIBLE "+i);
System.out.println(new String(readBuffer));
}
} catch (IOException ex) {
Logger.getLogger(SerialPortReader.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
}
最佳答案
结果是使用BufferedReader br = new BufferedReader(new InputStreamReader(InputStream)
而不是经典的 InputStream,但此解决方案会引发超时异常,因为超时默认设置为 0
。所以我添加了READ_TIMEOUT
一切都很顺利。
public void connect(String portName) throws Exception {
SerialPort serialPort = availiblePorts().get(portName);
if (serialPort.isOpen()) {
System.out.println("Error: Port is currently in use");
} else {
serialPort.openPort(2000);
serialPort.setComPortParameters(9600, 8, 1, 0);
serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING, 500, 0);
InputStream in = serialPort.getInputStream();
(new Thread(new SerialReader(in))).start();
}
}
关于java - 从串行端口读取整个消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52470100/