在步入正题前,发个牢骚。
前天总公司的一个技术经理下达一个任务,实现java程序与串口的通信。半天做出来了(见附件),经理看了,在电话里说是直接从网上下载的,颇为不屑。
说实话,当时真TM火大!虽然现在我还没有毕业,但是我也敢说我有实战经验!
我承认是下载了网上的一个例子,也从java的官方网站中copy了一些他们的代码,但是,绝对没有全部的copy,很多都是这几年实践下来的经验,还有文档说明也是自己实践出来的,关于串口测试的过程也是全程截图。
我敢说,现在项目中,不可能全部是自己的东西,如果什么都想要自己的,那还做什么飞机。创新也要从别人的基础上建立。
当然,这只是小弟的个人见解。
好吧,步入正题。
完整的代码+工具打包下载:点击打开链接
现在一般的电脑都没有串口端口的了,所以还是用虚拟的串口来做测试吧。
我们用 VSPD(Virtual Serial Port Driver) 这个软件建立两个虚拟串口,COM2和COM3,名字随便起,VSPD对虚拟串口的序号没有限制,理论上可以创建无数个。
串口通信类如下:
package org.serial;
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 javax.comm.CommPortIdentifier;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
/**
* @项目名称 :illegalsms
* @文件名称 :SerialPort.java
* @所在包 :org.serial
* @功能描述 :
* 串口类
* @创建者 :集成显卡 1053214511@qq.com
* @创建日期 :2012-9-13
* @修改记录 :
*/
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());
log("信息发送成功!");
}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 sp = new DSerialPort();
sp.listPort();
sp.selectPort(PORT_NAME);
sp.write("210.36.16.166");
sp.write("2");
sp.startRead(120);
}
上面代码中的PORT_NAME="COM2";
效果如下:
1.用 串口测试工具(附件中有) 打开COM3:
这个是和COM2连通的
如果在java程序中调用COM2,发送数据,那么COM3会收到,在COM3中发送的数据,java可以监听到。
2.运行java的main程序:
COM3中收到了信息:
从COM3中得到数据:
完整的代码+工具打包下载:点击打开链接
分享到:
相关推荐
这个实例项目展示了如何将这四个强大的工具集成为一套完整的自动化测试解决方案。 **Java**: Java是一种广泛使用的面向对象的编程语言,以其跨平台的特性闻名,非常适合编写自动化测试脚本。在自动化测试中,Java...
在本实例中,“VBA下基于MSCOMM串口通讯实例”着重展示了如何利用VBA与外部设备进行串口通信,特别是通过MSCOMM控件来实现这一功能。 串口通信是一种传统的通信方式,通常用于连接和交换数据,例如与嵌入式系统、...
Java串口通讯是一种在计算机与外部设备之间进行数据交换的方式,尤其在嵌入式系统、自动化设备、物联网应用中广泛应用。本实例通过Java Swing构建图形用户界面(GUI),实现了一个简单但实用的功能:读取TXT文件内容...
本文将详细探讨基于C#的串口通讯封装类及其在实时监控中的应用。 首先,C#作为.NET框架的主要编程语言,提供了丰富的库支持各种系统功能,包括串口通信。"串口通讯封装类.cs"和"串口设备通讯类.cs"是两个关键的源...
5. **Java小工程实例**: 压缩包内的“java串口通讯”很可能是一个简单的Java项目,包含了实现串口通讯的源代码。项目中可能有以下几个关键部分: - `SerialPort`类:用于代表串口对象,包含了打开、关闭串口,设置...
基于pytorch+LSTM的恶意域名检测实例python源码+文档说明+数据集(高分项目)基于pytorch+LSTM的恶意域名检测实例python源码+文档说明+数据集(高分项目)基于pytorch+LSTM的恶意域名检测实例python源码+文档说明+...
基于java的开发源码-OrientDB(基于Java的实例开发源码-文档数据库) 图形版.zip 基于java的开发源码-OrientDB(基于Java的实例开发源码-文档数据库) 图形版.zip 基于java的开发源码-OrientDB(基于Java的实例开发源码-...
Java串口编程是一种在Java应用程序中与物理串行端口进行通信的技术,广泛应用于设备控制、数据采集、物联网(IoT)应用等领域。本实例旨在通过简洁易懂的代码示例,帮助开发者理解如何在Java中实现串口通信。 首先,...
8. 测试计划:测试计划文档定义了测试的目标、策略、范围、资源和时间表,指导测试团队进行系统测试、集成测试和验收测试。 9. 测试分析报告:测试结束后,测试分析报告汇总了测试结果,包括发现的缺陷、修复情况、...
一个用户管理实例,基于Java+Hibernate+Flex+LCDS,包括用户添加\\编辑\\修改和查询!(说明:由于文件过大,包删除了WEB-INF下的lib文件夹,里面的内容请到LCDS下的flex.war中拷贝即可)
**基于MFC的串口通讯实例** 在计算机通信领域,串口通讯是一种常见的硬件接口,用于设备间的数据传输。MFC(Microsoft Foundation Classes)是微软提供的C++类库,它为Windows应用程序开发提供了丰富的功能,包括对...
基于Java的砂石矿山管理系统的设计与实现 (源码 + 说明文档 + 演示视频) 4 系统实现 16 4.1管理员功能模块 16 4.3员工功能模块 19 5 软件测试 23 5.1软件测试的重要性 23 5.2测试实例的研究与选择 23 5.3测试环境...
113-串口通讯(51单片机C语言实例Proteus仿真和代码)113-串口通讯(51单片机C语言实例Proteus仿真和代码)113-串口通讯(51单片机C语言实例Proteus仿真和代码)113-串口通讯(51单片机C语言实例Proteus仿真和代码)113-串口...
Java串口通信是一种在计算机与外部设备之间进行数据交换的方式,尤其在嵌入式系统、自动化设备、物联网应用中非常常见。在这个实例中,我们将会深入探讨如何利用Java语言实现串口通信,并通过提供的源码进行学习。 ...
接着,让我们了解Java串口通信的基本步骤: 1. **初始化串口**: 在Java程序中,我们需要创建一个`CommPortIdentifier`对象来识别可用的串口。这可以通过`CommPortIdentifier.getPortIdentifiers()`方法获取。然后,...
这个“Android串口通信实例”项目是基于Android Studio的一个实战项目,已经过测试,能够有效地执行串口的各种操作,如配置、开启、发送和接收数据。下面将详细讲解Android串口通信的相关知识点。 1. **Android串口...
基于MATLAB学习Kalman和最小二次的基本原理,其中kalman学习有execl实例源码+详细文档+全部数据(高分课程设计基于MATLAB学习Kalman和最小二次的基本原理,其中kalman学习有execl实例源码+详细文档+全部数据(高分...
基于SSM的宠物管理系统(源码 + 说明文档 + 演示视频) 第2章 系统分析 5 2.1 可行性分析 5 2.2总体设计原则 6 2.2 系统需求分析 6 2.3 业务流程分析 6 2.4 数据流图 7 第3章 系统设计 9 3.1 系统功能设计 9 3.2 ...