Java串口通信是嵌入式开发、工业控制、设备交互等场景中常见的技术需求,通过Java实现串口通信能够跨平台操作,简化开发流程,本文将从环境准备、核心API使用、代码实践及常见问题四个方面,详细讲解Java串口通信的具体实现方法。

环境准备:依赖库与驱动配置
在Java中实现串口通信,通常需要借助第三方库,最常用的是RXTXcomm或jSerialComm,以jSerialComm为例,它具有跨平台、API简洁、无需配置本地库等优势,推荐开发者优先使用。
添加依赖
若使用Maven项目,在pom.xml中添加以下依赖:
<dependency>
<groupId>com.fazecast</groupId>
<artifactId>jSerialComm</artifactId>
<version>2.9.3</version>
</dependency>
若为普通Java项目,可从jSerialComm官网下载对应版本的JAR包,并添加到项目类路径中。
驱动配置(仅Windows系统)
在Windows系统中,串口通信依赖于win32com.dll文件,jSerialComm会自动将所需的DLL文件打包到JAR中,但需确保运行时JAR文件未被压缩(避免使用某些压缩工具解压后丢失DLL),若遇到UnsatisfiedLinkError,可尝试将DLL文件手动解压到JAVA_HOME/bin目录下。
核心API解析:jSerialComm关键类
jSerialComm的核心类为SerialPort,通过该类可实现串口的打开、配置、读写及关闭操作,以下是主要API的功能说明:
获取可用串口列表
SerialPort[] ports = SerialPort.getCommPorts(); // 获取所有可用串口
for (SerialPort port : ports) {
System.out.println("串口名称: " + port.getSystemPortName());
System.out.println("描述信息: " + port.getDescriptivePortName());
}
通过该方法可列出当前系统中所有可用的串口设备,便于后续选择目标串口。
打开串口
SerialPort serialPort = SerialPort.getCommPort("COM3"); // 指定串口名称
if (serialPort.openPort()) {
System.out.println("串口打开成功");
} else {
System.out.println("串口打开失败,可能被占用或不存在");
}
openPort()方法用于打开指定串口,返回boolean类型表示操作是否成功,若串口已被其他程序占用,则会打开失败。

配置串口参数
串口通信需确保两端参数一致,主要包括波特率、数据位、停止位、校验位等,可通过setBaudRate()、setNumDataBits()等方法配置:
serialPort.setBaudRate(9600); // 波特率 serialPort.setDataBits(SerialPort.DATABITS_8); // 数据位(8位) serialPort.setStopBits(SerialPort.STOPBITS_1); // 停止位(1位) serialPort.setParity(SerialPort.NO_PARITY); // 无校验位
常用参数组合:9600, 8, 1, N(即波特率9600,8位数据位,1位停止位,无校验位),适用于大多数场景。
串口数据读写
-
读数据:可通过
readBytes()或readBytes(byte[], int)方法读取数据,建议结合setComPortTimeouts()设置超时时间,避免线程阻塞:// 设置超时:读取等待100ms,超时后返回已读取的数据 serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 100, 0); byte[] readBuffer = new byte[1024]; int numRead = serialPort.readBytes(readBuffer, readBuffer.length); if (numRead > 0) { String receivedData = new String(readBuffer, 0, numRead); System.out.println("接收数据: " + receivedData); } -
写数据:使用
writeBytes()方法向串口发送数据:String sendData = "Hello, Serial Port!"; byte[] writeBuffer = sendData.getBytes(); int numWritten = serialPort.writeBytes(writeBuffer, writeBuffer.length); if (numWritten == writeBuffer.length) { System.out.println("发送数据成功: " + sendData); }
关闭串口
通信完成后需关闭串口,释放资源:
serialPort.closePort();
完整代码示例:双向通信实践
以下是一个简单的串口双向通信示例,实现发送指令并接收设备返回数据:
import com.fazecast.jSerialComm.*;
public class SerialPortExample {
public static void main(String[] args) {
// 1. 获取并打开串口
SerialPort serialPort = SerialPort.getCommPort("COM3");
if (!serialPort.openPort()) {
System.out.println("串口打开失败");
return;
}
System.out.println("串口打开成功: " + serialPort.getSystemPortName());
// 2. 配置串口参数
serialPort.setBaudRate(9600);
serialPort.setDataBits(SerialPort.DATABITS_8);
serialPort.setStopBits(SerialPort.STOPBITS_1);
serialPort.setParity(SerialPort.NO_PARITY);
// 3. 设置超时机制
serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 100, 0);
// 4. 发送数据
String sendMsg = "GET_DATA";
byte[] sendBytes = sendMsg.getBytes();
serialPort.writeBytes(sendBytes, sendBytes.length);
System.out.println("已发送: " + sendMsg);
// 5. 接收数据
try {
Thread.sleep(500); // 等待设备响应
} catch (InterruptedException e) {
e.printStackTrace();
}
byte[] readBuffer = new byte[1024];
int numRead = serialPort.readBytes(readBuffer, readBuffer.length);
if (numRead > 0) {
String receivedMsg = new String(readBuffer, 0, numRead).trim();
System.out.println("已接收: " + receivedMsg);
}
// 6. 关闭串口
serialPort.closePort();
System.out.println("串口已关闭");
}
}
常见问题与解决方案
-
串口被占用

- 现象:
openPort()返回false,提示“端口被占用”。 - 解决:检查是否有其他程序或线程正在使用该串口,可通过设备管理器关闭串口或更换串口号。
- 现象:
-
数据乱码或丢失
- 现象:接收数据与发送数据不一致,或部分数据未收到。
- 解决:检查串口参数(波特率、数据位等)是否与设备端一致;调整超时时间,避免数据读取不及时。
-
UnsatisfiedLinkError错误- 现象:运行时提示找不到本地库。
- 解决:确保jSerialComm的JAR包完整,或在Windows系统中将DLL文件放到
JAVA_HOME/bin目录。
-
Linux/macOS下串口权限问题
- 现象:非root用户无法访问串口(如
/dev/ttyUSB0)。 - 解决:通过命令
chmod 666 /dev/ttyUSB0修改串口权限,或配置用户组规则。
- 现象:非root用户无法访问串口(如
Java串口通信通过jSerialComm等库可高效实现跨平台设备交互,开发过程中需重点关注串口参数配置、数据读写超时处理及资源释放,同时结合实际场景调试通信逻辑,掌握上述方法后,可快速应用于工业控制、智能家居、传感器数据采集等项目中。




















