RXTX串列埠通訊 java程式碼實現
阿新 • • 發佈:2019-02-14
package com.runtrial.lms.rxtx; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.TooManyListenersException; import gnu.io.CommPortIdentifier; import gnu.io.PortInUseException; import gnu.io.SerialPort; import gnu.io.SerialPortEvent; import gnu.io.SerialPortEventListener; /** * @專案名稱 :illegalsms * @檔名稱 :SerialPort.java * @所在包 :org.serial * @功能描述 : 串列埠類 * @修改記錄 : */ public class DSerialPort implements Runnable, SerialPortEventListener { private String appName = "串列埠通訊測試[整合顯示卡2012]"; private int timeout = 2000;// open 埠時的等待時間 private int threadTime = 0; private CommPortIdentifier commPort; private SerialPort serialPort; private InputStream inputStream; private OutputStream outputStream; /** * @方法名稱 :listPort * @功能描述 :列出所有可用的串列埠 * @返回值型別 :void */ @SuppressWarnings("rawtypes") public void listPort() { CommPortIdentifier cpid; Enumeration en = CommPortIdentifier.getPortIdentifiers(); System.out.println("now to list all Port of this PC:" + en); while (en.hasMoreElements()) { cpid = (CommPortIdentifier) en.nextElement(); if (cpid.getPortType() == CommPortIdentifier.PORT_SERIAL) { System.out.println(cpid.getName() + ", " + cpid.getCurrentOwner()); } } } /** * @方法名稱 :selectPort * @功能描述 :選擇一個埠,比如:COM1 * @返回值型別 :void * @param portName */ @SuppressWarnings("rawtypes") public void selectPort(String portName) { this.commPort = null; CommPortIdentifier cpid; Enumeration en = CommPortIdentifier.getPortIdentifiers(); while (en.hasMoreElements()) { cpid = (CommPortIdentifier) en.nextElement(); if (cpid.getPortType() == CommPortIdentifier.PORT_SERIAL && cpid.getName().equals(portName)) { this.commPort = cpid; break; } } openPort(); } /** * @方法名稱 :openPort * @功能描述 :開啟SerialPort * @返回值型別 :void */ private void openPort() { if (commPort == null) log(String.format("無法找到名字為'%1$s'的串列埠!", commPort.getName())); else { log("埠選擇成功,當前埠:" + commPort.getName() + ",現在例項化 SerialPort:"); try { serialPort = (SerialPort) commPort.open(appName, timeout); log("例項 SerialPort 成功!"); } catch (PortInUseException e) { throw new RuntimeException(String.format("埠'%1$s'正在使用中!", commPort.getName())); } } } /** * @方法名稱 :checkPort * @功能描述 :檢查埠是否正確連線 * @返回值型別 :void */ private void checkPort() { if (commPort == null) throw new RuntimeException("沒有選擇埠,請使用 " + "selectPort(String portName) 方法選擇埠"); if (serialPort == null) { throw new RuntimeException("SerialPort 物件無效!"); } } /** * @方法名稱 :write * @功能描述 :向埠傳送資料,請在呼叫此方法前 先選擇埠,並確定SerialPort正常開啟! * @返回值型別 :void * @param message */ public void write(String message) { checkPort(); try { outputStream = new BufferedOutputStream(serialPort.getOutputStream()); } catch (IOException e) { throw new RuntimeException("獲取埠的OutputStream出錯:" + e.getMessage()); } try { outputStream.write(message.getBytes("GBK"), 0, message.getBytes("GBK").length); //outputStream.write(message.getBytes()); log("資訊傳送成功!"+new String(message.getBytes())); } catch (IOException e) { throw new RuntimeException("向埠傳送資訊時出錯:" + e.getMessage()); } finally { try { outputStream.close(); } catch (Exception e) { } } } /** * @方法名稱 :startRead * @功能描述 :開始監聽從埠中接收的資料 * @返回值型別 :void * @param time * 監聽程式的存活時間,單位為秒,0 則是一直監聽 */ public void startRead(int time) { checkPort(); try { inputStream = new BufferedInputStream(serialPort.getInputStream()); } catch (IOException e) { throw new RuntimeException("獲取埠的InputStream出錯:" + e.getMessage()); } try { serialPort.addEventListener(this); } catch (TooManyListenersException e) { throw new RuntimeException(e.getMessage()); } serialPort.notifyOnDataAvailable(true); log(String.format("開始監聽來自'%1$s'的資料--------------", commPort.getName())); if (time > 0) { this.threadTime = time * 1000; Thread t = new Thread(this); t.start(); log(String.format("監聽程式將在%1$d秒後關閉。。。。", threadTime)); } } /** * @方法名稱 :close * @功能描述 :關閉 SerialPort * @返回值型別 :void */ public void close() { serialPort.close(); serialPort = null; commPort = null; } public void log(String msg) { System.out.println(appName + " --> " + msg); } /** * 資料接收的監聽處理函式 */ @Override public void serialEvent(SerialPortEvent arg0) { switch (arg0.getEventType()) { case SerialPortEvent.BI:/* Break interrupt,通訊中斷 */ case SerialPortEvent.OE:/* Overrun error,溢位錯誤 */ case SerialPortEvent.FE:/* Framing error,傳幀錯誤 */ case SerialPortEvent.PE:/* Parity error,校驗錯誤 */ case SerialPortEvent.CD:/* Carrier detect,載波檢測 */ case SerialPortEvent.CTS:/* Clear to send,清除傳送 */ case SerialPortEvent.DSR:/* Data set ready,資料裝置就緒 */ case SerialPortEvent.RI:/* Ring indicator,響鈴指示 */ case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/* * Output buffer is * empty,輸出緩衝區清空 */ break; case SerialPortEvent.DATA_AVAILABLE:/* * Data available at the serial * port,埠有可用資料。讀到緩衝陣列,輸出到終端 */ byte[] readBuffer = new byte[1024]; String readStr = ""; String s2 = ""; try { while (inputStream.available() > 0) { inputStream.read(readBuffer); readStr += new String(readBuffer).trim(); } s2 = new String(readBuffer).trim(); log("接收到埠返回資料(長度為" + readStr.length() + "):" + readStr); log(s2); } catch (IOException e) { } } } @Override public void run() { try { Thread.sleep(threadTime); serialPort.close(); log(String.format("埠''監聽關閉了!", commPort.getName())); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { DSerialPort dp = new DSerialPort(); dp.listPort(); dp.selectPort("COM2"); dp.write("我要報警啦"); dp.startRead(30); } }