我正在使用JSSC串行端口包在我的應用程序和連接到串行端口的設備之間交換數據。我做了一個簡單的應用程序,它可以發送識別信息到設備並打印迴應。我希望它能抵抗連接錯誤(例如在通信期間拔掉電纜後)。JSSC - 斷開連接會導致阻塞串行端口
操作順序初始化 - >打開 - > IDN - >關閉完美。 當我在打開端口後拔下電纜時,我無法發送消息(對我來說似乎是合乎邏輯的)並關閉了端口(沒有什麼東西可以關閉了,所以我也明白了)。
一開始我很驚訝我再次插上電纜後無法關閉端口,但我發現在每次連接設備後,OS會給它一個不同的號碼,JSSC庫用它來處理端口。幸運的是,事實證明,只需在重新連接後打開端口即可解決所有問題,因爲應用程序可以再次發送消息。
不幸的是,當端口被打開時有更多的斷開/連接電纜的嘗試出現問題。每次嘗試後,應用程序的運行速度越來越慢,以至於無法再發送消息的狀態結束。另一件事是,在這種狀態下,所有串口(不僅是我試圖與之通信的那一個)都被阻塞,我甚至無法通過終端類應用程序訪問它們。
所以,問題是:
我怎樣才能讓應用程序是連接中斷性不阻塞端口和鬆動的表現?
我想這可能是關於某種資源,內存管理等,但是我對這些東西的瞭解還不足以自己解決問題。
執行通信的:
import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
class Connection implements SerialPortEventListener {
private static final int SERIAL_PORT_BAUD_RATE = 9600;
private static final int SERIAL_PORT_DATA_BITS_NUMBER = 8;
private static final int SERIAL_PORT_STOP_BITS_NUMBER = 1;
private static final int SERIAL_PORT_PARITY = 0;
private SerialPort serialPort;
private String portName;
public Connection(String portName) {
this.portName = portName;
}
public void open() throws SerialPortException {
serialPort = new SerialPort(portName);
serialPort.openPort();
serialPort.setParams(SERIAL_PORT_BAUD_RATE,
SERIAL_PORT_DATA_BITS_NUMBER,
SERIAL_PORT_STOP_BITS_NUMBER,
SERIAL_PORT_PARITY);
serialPort.addEventListener(this);
}
public void close() throws SerialPortException {
if (serialPort != null) {
serialPort.closePort();
}
}
public void simpleMessage() throws SerialPortException {
if (serialPort != null) {
serialPort.writeString("IDN");
}
}
@Override
public void serialEvent(SerialPortEvent serialPortEvent) {
if (serialPortEvent.getEventType() == SerialPortEvent.RXCHAR) {
try {
System.out.println(serialPort.readString());
} catch (SerialPortException e) {
System.out.println("Error while reading a string.");
}
}
}
}
主類:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.io.IOException;
public class MainApplication extends Application{
public static void main(String [] args) {
Application.launch();
}
@Override
public void start(Stage primaryStage) throws Exception {
Pane rootPane = null;
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApplication.class.getResource("front.fxml"));
try{
rootPane = loader.load();
} catch (IOException exception) {
exception.printStackTrace();
}
Scene scene = new Scene(rootPane);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setOnCloseRequest(event -> {
Platform.exit();
System.exit(0);
});
}
}
FXML代碼:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
<StackPane fx:id="rootPane"
xmlns="http://javafx.com/javafx/8.0.60"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="FrontController">
<VBox>
<Button text="Init" onAction="#init"/>
<Button text="Open" onAction="#openPort"/>
<Button text="Close" onAction="#closePort"/>
<Button text="IDN" onAction="#idn"/>
<Button text="Get Ports" onAction="#getPorts"/>
<Button text="Is opened?" onAction="#isPortOpen"/>
</VBox>
</StackPane>
控制器:
import javafx.fxml.FXML;
import jssc.SerialPortException;
import jssc.SerialPortList;
import java.util.Arrays;
public class FrontController {
private Connection connection;
@FXML
private void init() {
String portName = "COM4";
connection = new Connection(portName);
}
@FXML
private void openPort() {
try {
connection.open();
} catch (SerialPortException e) {
e.printStackTrace();
}
}
@FXML
private void closePort() {
try {
connection.close();
} catch (SerialPortException e) {
e.printStackTrace();
}
}
@FXML
private void idn() {
try {
connection.idnMessage();
} catch (SerialPortException e) {
e.printStackTrace();
}
}
@FXML
private void getPorts() {
System.out.println(Arrays.toString(SerialPortList.getPortNames()));
}
@FXML
private void isPortOpen() {
System.out.println(connection.getSerialPort().isOpened());
}
}