由于是网络串口通信,字节传输,所以考虑到各种情况
- 中文乱码,(UTF-8)
- 传输和接收都是按字节的,会出现粘包/拆包问题。
- 网络通讯往往是间断性的,一串字节往往分几批进行发送。
设置串口的listener
1 @Override 2 public void serialEvent(SerialPortEvent arg0) { 3 if(arg0.getEventType() == SerialPortEvent.DATA_AVAILABLE) {//数据通知 4 byte[] bytes = readData(serialPort); 5 System.out.println("收到的数据长度:"+bytes.length); 6 String receiveData = null; 7 receiveData = new String(bytes); 8 System.out.println("收到的数据:" + receiveData); 9 handleReceiveData(receiveData); 10 } 11 }
网上很多都是按这种方式读取的,这种方式我感觉会出现很多问题,所以不建议
1 /** 2 * 从串口读取数据 3 * @param serialPort 要读取的串口(不建议) 4 * @return 读取的数据 5 */ 6 private static byte[] readData(SerialPort serialPort) { 7 InputStream is = null; 8 byte[] bytes = null; 9 try { 10 is = serialPort.getInputStream();//获得串口的输入流 11 int bufflenth = is.available();//获得数据长度 12 while (bufflenth != 0) { 13 bytes = new byte[bufflenth];//初始化byte数组 14 is.read(bytes); 15 bufflenth = is.available(); 16 } 17 } catch (IOException e) { 18 logger.error("串口异常,停止服务。", e); 19 System.exit(-1); 20 } finally { 21 try { 22 if (is != null) { 23 is.close(); 24 is = null; 25 } 26 } catch(IOException e) { 27 e.printStackTrace(); 28 } 29 } 30 return bytes; 31 }
因为is.available()方法是估值,网络传输不能使用此方法。
目前我使用的是按一个字节读取,直到inputStream.read(byte) == 0为结束。
1 private static byte[] readData(SerialPort serialPort) { 2 InputStream in = null; 3 byte[] bytes = {}; 4 try { 5 in = serialPort.getInputStream(); 6 // 缓冲区大小为一个字节 7 byte[] readBuffer = new byte[1]; 8 int bytesNum = in.read(readBuffer); 9 int sum = bytesNum; 10 while (bytesNum > 0) { 11 bytes = concat(bytes, readBuffer); 12 bytesNum = in.read(readBuffer); 13 } 14 } catch (IOException e) { 15 e.printStackTrace(); 16 } finally { 17 try { 18 if (in != null) { 19 in.close(); 20 in = null; 21 } 22 } catch (IOException e) { 23 e.printStackTrace(); 24 } 25 } 26 return bytes; 27 28 }
此种方法可能一股脑接收了多次数据,以" " 为传输一次的分割。处理接收到的字符串
1 private static synchronized void handleReceivedData(String data) { 2 System.out.println("handleReceivedData--->" + data); 3 if(data == null){ 4 System.out.println("收到的数据为null,不处理。"); 5 }else { 6 if(!data.endsWith("\n")) { 7 allReceiveString += data; 8 return ; 9 } 10 data = allReceiveString + data; 11 allReceiveString = ""; 12 String[] strs = data.split("\\n"); 13 System.out.println("收到的次数:" + strs.length); 14 for (String str : strs) { 15 System.out.println(str); 16 } 17 } 18 19 }
1 ------------------------------------------------------------------------------- 2 收到的数据长度:60 3 收到的数据:hello;;;;; hello;;;;; world,,,,;; 你好,世界,,,,;; 4 handleReceivedData--->hello;;;;; hello;;;;; world,,,,;; 你好,世界,,,,;; 5 收到的次数:4 6 hello;;;;; 7 hello;;;;; 8 world,,,,;; 9 你好,世界,,,,;;