通常,串口通信应用程序有两种模式,一种是实现SerialPortEventListener接口,监听各种串口事件并作相应处理;另一种是建立一个独立的接收线程专门负责数据的接收。但这两种方法在某些情况下存在很严重的问题。
事件监听模型
事件监听模型的运作方式:
(1)首先需要在端口控制类(如SerialManager)加上“implements SerialPortEventListener”
(2)在初始化时加入如下代码:
try {
SerialPort sPort.addEventListener(SerialManager);
}
catch (TooManyListenersException e) {
throw new SerialConnectionException("too many listeners added");
sPort.close();
}
sPort.notifyOnDataAvailable(true);
(3)覆写public void serialEvent(SerialPortEvent e)方法,在其中对事件进行判断。
BI -通讯中断.
CD -载波检测.
CTS -清除发送.
DATA_AVAILABLE -有数据到达.
DSR -数据设备准备好.
FE -帧错误.
OE -溢位错误.
OUTPUT_BUFFER_EMPTY -输出缓冲区已清空.
PE -奇偶校验错.
RI - 振铃指示.
一般最常用的就是DATA_AVAILABLE--串口有数据到达事件。也就是说当串口有数据到达时,可以在serialEvent中接收并处理所收到的数据。此模式存在的问题:数据有丢失。
串口读数据的线程模型
这个模型顾名思义,就是将接收数据的操作写成一个线程的形式。将收到的数据打包放到一个缓存中,然后启动另一个线程从缓存中获取并处理数据。两个线程以生产者—消费者模式协同工作,数据的流向如下图所示:
public byte[] getPack(){
while (true) {
// PacketLength为数据包长度
byte[] msgPack = new byte[PacketLength];
if( (newData = is.read()) != -1){
for(int i = 0; i < PacketLength; i++){
msgPack[i] = (byte) newData;
}
System.out.println(msgPack[i]);
}
}
return msgPack;
}