├── README.md
├── application.properties
├── bin
└── rxtx-0.0.1-SNAPSHOT.jar
├── pom.xml
└── src
├── main
└── java
│ └── com
│ └── linchunsen
│ └── rxtx
│ ├── JdbcUtil.java
│ ├── MessageParseAble.java
│ ├── SerialAbstarctListener.java
│ ├── SerialContext.java
│ ├── SerialPortRxtx.java
│ ├── SerialReader.java
│ ├── SerialStarter.java
│ └── SerialWriter.java
└── test
└── java
└── com
└── linchunsen
└── rxtx
└── example
├── Main.java
└── MessageParse.java
/README.md:
--------------------------------------------------------------------------------
1 | # rxtx
2 | 对java的通信框架rxtx进行了进一步的封装,通过传入properties对象便可以实现串口的监听配置
3 |
4 | ## 目录说明
5 | bin : 项目导出的jar包
6 |
7 | src/main : 项目的源代码
8 |
9 | src/test : 项目的示例代码
10 |
11 | application.properties : 项目的配置文件,里面包含项目的详细配置说明
12 |
--------------------------------------------------------------------------------
/application.properties:
--------------------------------------------------------------------------------
1 | ##----------------------------##
2 | ##数据库配置
3 |
4 | #指示当前的数据库配置是否是加过密的
5 | # true表示"是"
6 | # false表示"否",默认值:否
7 | myJdbcUtil.isEncodedInfo=true
8 | #数据库driverName
9 | myJdbcUtil.driverName=Y29tLm1pY3Jvc29mdC5zcWxzZXJ2ZXIuamRiYy5TUUxTZXJ2ZXJEcml2ZXI=
10 | #数据库url
11 | myJdbcUtil.url=amRiYzpzcWxzZXJ2ZXI6Ly8xMC4xMzUuMi4yNTA6MTQzMzsgRGF0YWJhc2VOYW1lPWRhcw==
12 | #数据库user
13 | myJdbcUtil.user=c2FjdWl5dXNoYW4=
14 | #数据库password
15 | myJdbcUtil.password=Q1lTY3lzMTIzNDU2
16 |
17 | ##----------------------------##
18 | ##串口设置
19 | #
20 | ##说明:
21 | # 程序读取配置文件时,将会扫描以serial.rxtx为前缀的键,并以serial.rxtx.*为完整前缀,根据不同前缀的数目,配置并监听多个串口
22 | # 例如,当配置文件中同时出现serial.rxtx.com1.appName和serial.rxtx.com4.appName程序将会同时监听这两串口
23 |
24 | #COM1串口通信配置
25 | #延时等待端口数据准备的时间,端口读入数据事件触发后,等待n毫秒后再读取,以便让数据一次性读完,默认值是1,单位是毫秒
26 | serial.rxtx.com1.delayRead=1
27 | #超时时间的配置值,默认值是3000,单位是毫秒
28 | serial.rxtx.com1.timeout=3000
29 | #串口名,默认值是serial.rxtx前缀的最后一个单词,如前缀serial.rxtx.com1则默认串口名为COM1,程序将会自动将小写转为大写
30 | serial.rxtx.com1.port=COM1
31 | #数据位的配置值,默认值是8,可能的取值是5,6,7,8
32 | serial.rxtx.com1.dataBits=8
33 | #停止位的配置值,默认值是1,可能的取值是1,1.5,2
34 | serial.rxtx.com1.stopBits=1
35 | #奇偶校验的配置值,0表示无校验,1表示奇/ODD校验,2表示偶/EVEN校验,默认值是无校验
36 | serial.rxtx.com1.parity=0
37 | #波特率的配置值,默认值是115200
38 | serial.rxtx.com1.rate=115200
39 | #串口的程序名,默认值是SerialRXTX,可以重复,无实际意义
40 | serial.rxtx.com1.appName="SerialRXTX"
41 |
42 | #COM4串口通信配置
43 | serial.rxtx.com4.appName="SerialRXTX"
--------------------------------------------------------------------------------
/bin/rxtx-0.0.1-SNAPSHOT.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demoModel/rxtx/bb2eb110d28a3e40f96562660c5cc4e0f6d6fcdf/bin/rxtx-0.0.1-SNAPSHOT.jar
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | com.yuanqitec.framework
5 | rxtx
6 | 0.0.1-SNAPSHOT
7 |
8 |
9 |
10 | org.apache.maven.plugins
11 | maven-compiler-plugin
12 | 3.1
13 |
14 | 1.8
15 | 1.8
16 | UTF-8
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/main/java/com/linchunsen/rxtx/JdbcUtil.java:
--------------------------------------------------------------------------------
1 | package com.linchunsen.rxtx;
2 |
3 | import java.io.IOException;
4 | import java.io.UnsupportedEncodingException;
5 | import java.sql.Connection;
6 | import java.sql.DriverManager;
7 | import java.sql.SQLException;
8 | import java.util.Properties;
9 |
10 | import sun.misc.BASE64Decoder;
11 | import sun.misc.BASE64Encoder;
12 |
13 | /**
14 | *
15 | * 简介
根据配置文件对象来获取数据库Connection的工具类
16 | *
17 | *
18 | * 文件修改记录
19 | *
20 | * 修改日期 |
21 | * 修改人 |
22 | * 修改内容 |
23 | *
24 | *
25 | *
26 | * 2017年1月6日 |
27 | * linchunsen |
28 | * 新建文件,并实现基本功能 |
29 | *
30 | *
31 | *
32 | */
33 | public class JdbcUtil {
34 |
35 | private boolean isLoaded = false;
36 | /**
37 | * 配置文件的键头
38 | */
39 | public static final String MYJDBC_KEY_BASE = "myJdbcUtil.";
40 | /**
41 | * 配置文件中isEncodedInfo的键
42 | */
43 | public static final String MYJDBC_KEY_ISENCODEDINFO = "isEncodedInfo";
44 | /**
45 | * 配置文件中driverName的键
46 | */
47 | public static final String MYJDBC_KEY_DRIVERNAME = "driverName";
48 | public String driverName;
49 | /**
50 | * 配置文件中user的键
51 | */
52 | public static final String MYJDBC_KEY_USER = "user";
53 | public String user;
54 | /**
55 | * 配置文件中password的键
56 | */
57 | public static final String MYJDBC_KEY_PASSWORD = "password";
58 | public String password;
59 | /**
60 | * 配置文件中url的键
61 | */
62 | public static final String MYJDBC_KEY_URL = "url";
63 | public String url;
64 |
65 | /**
66 | * 根据配置文件对象来加载数据源配置
67 | *
68 | * @param properties 要加载的配置文件对象
69 | * @throws IOException
70 | */
71 | public void load(Properties properties) throws IOException {
72 |
73 | String isEncodedInfo=properties.getProperty(JdbcUtil.MYJDBC_KEY_BASE+JdbcUtil.MYJDBC_KEY_ISENCODEDINFO, null);
74 | String driverName = properties.getProperty(JdbcUtil.MYJDBC_KEY_BASE+JdbcUtil.MYJDBC_KEY_DRIVERNAME);
75 | String user = properties.getProperty(JdbcUtil.MYJDBC_KEY_BASE+JdbcUtil.MYJDBC_KEY_USER);
76 | String password = properties.getProperty(JdbcUtil.MYJDBC_KEY_BASE+JdbcUtil.MYJDBC_KEY_PASSWORD);
77 | String url = properties.getProperty(JdbcUtil.MYJDBC_KEY_BASE+JdbcUtil.MYJDBC_KEY_URL);
78 |
79 | if (isEncodedInfo!=null) {
80 | boolean isEncoded=Boolean.parseBoolean(isEncodedInfo);
81 | if (isEncoded) {//是已经加密过的配置信息
82 | this.driverName = getFromBase64(driverName);
83 | this.user = getFromBase64(user);
84 | this.password = getFromBase64(password);
85 | this.url = getFromBase64(url);
86 | } else {//不是已经加密过的配置信息,将在本次加密
87 | this.driverName=driverName;
88 | this.user=user;
89 | this.url=url;
90 | this.password=password;
91 | //加密配置信息
92 | driverName=getBase64(driverName);
93 | user=getBase64(user);
94 | url=getBase64(url);
95 | password=getBase64(password);
96 | isEncoded=true;
97 | }
98 | } else {//配置文件中没有配置项
99 | this.driverName=driverName;
100 | this.user=user;
101 | this.url=url;
102 | this.password=password;
103 | }
104 |
105 | this.isLoaded = true;
106 | }
107 |
108 | /**
109 | * 在执行了load(Properties properties)之后,才可以调用获取数据库的Connection实例
110 | *
111 | * @return Connection实例
112 | * @throws ClassNotFoundException
113 | * @throws SQLException
114 | */
115 | public Connection getConnection() throws ClassNotFoundException, SQLException {
116 | Connection connection = null;
117 | if (isLoaded) {
118 | Class.forName(driverName);
119 | connection = DriverManager.getConnection(this.url, this.user, this.password);
120 | } else {
121 | throw new RuntimeException("未执行load(Properties properties)方法,执行该方法后重试");
122 | }
123 | return connection;
124 | }
125 |
126 | /**
127 | * 将经过Base64转码的字符串还原
128 | *
129 | * @param source
130 | * 经过Base64转码的字符串
131 | * @return 还原的字符串
132 | * @throws IOException
133 | */
134 | public String getFromBase64(String source) throws IOException {
135 | String result = null;
136 | byte[] bytes = null;
137 | if (source != null) {
138 | BASE64Decoder decoder = new BASE64Decoder();
139 | bytes = decoder.decodeBuffer(source);
140 | result = new String(bytes, "utf-8");
141 | }
142 | return result;
143 | }
144 |
145 | /**
146 | * 将目标字符串使用Base64进行编码
147 | *
148 | * @throws UnsupportedEncodingException
149 | */
150 | public String getBase64(String source) throws UnsupportedEncodingException {
151 | String result = null;
152 | byte[] bytes = null;
153 | bytes = source.getBytes("utf-8");
154 | if (bytes != null) {
155 | BASE64Encoder encoder = new BASE64Encoder();
156 | result = encoder.encode(bytes);
157 | }
158 | return result;
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/src/main/java/com/linchunsen/rxtx/MessageParseAble.java:
--------------------------------------------------------------------------------
1 | package com.linchunsen.rxtx;
2 |
3 | /**
4 | *
5 | * 简介
报文解析接口,只有实现了该接口的类才能被串口读取器所调用以解析报文
6 | *
7 | *
8 | * 文件修改记录
9 | *
10 | * 修改日期 |
11 | * 修改人 |
12 | * 修改内容 |
13 | *
14 | *
15 | *
16 | * 2016年12月29日 |
17 | * linchunsen |
18 | * 新建文件,并实现基本功能 |
19 | *
20 | *
21 | *
22 | */
23 | public interface MessageParseAble {
24 | /**
25 | * 解析执行报文
26 | *
27 | * @param message
28 | * 报文
29 | * @throws Exception
30 | */
31 | void messageParse(String message) throws Exception;
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/linchunsen/rxtx/SerialAbstarctListener.java:
--------------------------------------------------------------------------------
1 | package com.linchunsen.rxtx;
2 |
3 | import java.io.InputStream;
4 | import java.io.OutputStream;
5 | import java.util.Observable;
6 |
7 | import gnu.io.SerialPortEvent;
8 | import gnu.io.SerialPortEventListener;
9 |
10 | /**
11 | *
12 | * 简介
串口事件监听的抽象实现,对串口监听监听器进行了进一步的封装
13 | *
14 | *
15 | * 文件修改记录
16 | *
17 | * 修改日期 |
18 | * 修改人 |
19 | * 修改内容 |
20 | *
21 | *
22 | *
23 | * 2017年1月4日 |
24 | * linchunsen |
25 | * 新建文件,并实现基本功能 |
26 | *
27 | *
28 | *
29 | */
30 | public abstract class SerialAbstarctListener extends Observable implements SerialPortEventListener {
31 |
32 | /**
33 | * 串口实例
34 | */
35 | private SerialPortRxtx serialPortRxtx;
36 | /**
37 | * 读写延迟
38 | */
39 | private long delayReadTime;
40 |
41 | public SerialAbstarctListener(SerialPortRxtx serialPortRxtx) {
42 | super();
43 | this.serialPortRxtx = serialPortRxtx;
44 | this.delayReadTime=serialPortRxtx.getSerialContext().getDelay();
45 | }
46 |
47 | /**
48 | * {@link SerialPortEventListener}接口的实现类
49 | */
50 | @Override
51 | public void serialEvent(SerialPortEvent event) {
52 | if (serialPortRxtx.isOpen()) {
53 | try {
54 | Thread.sleep(delayReadTime);
55 | } catch (InterruptedException e) {
56 | e.printStackTrace();
57 | }
58 | switch (event.getEventType()) {
59 | case SerialPortEvent.BI: // 10
60 | case SerialPortEvent.OE: // 7
61 | case SerialPortEvent.FE: // 9
62 | case SerialPortEvent.PE: // 8
63 | case SerialPortEvent.CD: // 6
64 | case SerialPortEvent.CTS: // 3
65 | case SerialPortEvent.DSR: // 4
66 | case SerialPortEvent.RI: // 5
67 | case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2
68 | break;
69 | case SerialPortEvent.DATA_AVAILABLE: // 1
70 | InputStream inputStream = serialPortRxtx.getInputStream();
71 | OutputStream outputStream = serialPortRxtx.getOutputStream();
72 | readerAndWriter(inputStream, outputStream);
73 | break;
74 | }
75 | } else {
76 | throw new RuntimeException("串口未开启,请查看是否执行了SerialPortRxtx类的open()方法");
77 | }
78 | }
79 |
80 | /**
81 | * 每次在接收合法数据时执行的读写操作 无返回
82 | *
83 | * @param inputStream
84 | * 串口输入流
85 | * @param outputStream
86 | * 串口输出流
87 | */
88 | public abstract void readerAndWriter(InputStream inputStream, OutputStream outputStream);
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/linchunsen/rxtx/SerialContext.java:
--------------------------------------------------------------------------------
1 | package com.linchunsen.rxtx;
2 |
3 | import java.util.Properties;
4 |
5 | import gnu.io.SerialPort;
6 |
7 | /**
8 | *
9 | * 简介
串口通信的上下文,包含了串口的配置信息
10 | *
11 | *
12 | * 文件修改记录
13 | *
14 | * 修改日期 |
15 | * 修改人 |
16 | * 修改内容 |
17 | *
18 | *
19 | *
20 | * 2017年1月4日 |
21 | * linchunsen |
22 | * 新建文件,并实现基本功能 |
23 | *
24 | *
25 | *
26 | */
27 | public class SerialContext {
28 | /**
29 | * 配置文件中的key的基础部分(key前缀),即完整的key=key前缀+"."+"端口名"+"."+key
30 | */
31 | private final static String SERIAL_RXTX_BASE_KEY = "serial.rxtx.";
32 | /**
33 | * 延时等待端口数据准备的时间,端口读入数据事件触发后,等待n毫秒后再读取,以便让数据一次性读完
34 | */
35 | public static final String SERIAL_DELAY_KEY = "delayRead";
36 | /**
37 | * 延时等待端口数据准备的时间的配置值
38 | */
39 | private int delay = 1;
40 |
41 | /**
42 | * 超时时间
43 | */
44 | public static final String SERIAL_TIMEOUT_KEY = "timeout";
45 | /**
46 | * 超时时间的配置值
47 | */
48 | private int timeout = 3000;
49 |
50 | /**
51 | * 端口名称
52 | */
53 | public static final String SERIAL_PORT_KEY = "port";
54 | /**
55 | * 端口名称的配置值
56 | */
57 | private String port = "COM3";
58 |
59 | /**
60 | * 数据位
61 | */
62 | public static final String SERIAL_DATABITS_KEY = "dataBits";
63 | /**
64 | * 数据位的配置值
65 | */
66 | private int dataBits = SerialPort.DATABITS_8;
67 |
68 | /**
69 | * 停止位
70 | */
71 | public static final String SERIAL_STOPBITS_KEY = "stopBits";
72 | /**
73 | * 停止位的配置值
74 | */
75 | private int stopBits = SerialPort.STOPBITS_1;
76 |
77 | /**
78 | * 奇偶校验
79 | */
80 | public static final String SERIAL_PARITY_KEY = "parity";
81 | /**
82 | * 奇偶校验的配置值
83 | */
84 | private int parity = SerialPort.PARITY_NONE;
85 |
86 | /**
87 | * 波特率
88 | */
89 | public static final String SERIAL_RATE_KEY = "rate";
90 | /**
91 | * 波特率的配置值
92 | */
93 | private int rate = 115200;
94 |
95 | /**
96 | * 应用名
97 | * */
98 | public static final String SERIAL_APP_KEY = "appName";
99 | /**
100 | * 应用名的默认名为SerialRXTX
101 | */
102 | private String appName = "SerialRXTX";
103 |
104 | /**
105 | * 串口上下文的构造方法,采用默认配置 无返回 无参数
106 | *
107 | * @author linchunsen
108 | */
109 | public SerialContext() {
110 |
111 | }
112 |
113 | /**
114 | * 串口上下文的构造方法,根据传入的配置和key前缀加载配置 无返回
115 | *
116 | * @param properties
117 | * 传入的配置
118 | * @param keyBase
119 | * key前缀
120 | * @author linchunsen
121 | */
122 | public SerialContext(Properties properties, String portName) {
123 | this.port=portName.toUpperCase();
124 | loadProperties(properties, SerialContext.SERIAL_RXTX_BASE_KEY +portName);
125 | }
126 |
127 | /**
128 | * 根据系统配置和key前缀加载配置 无返回
129 | *
130 | * @param properties
131 | * 传入的配置
132 | * @param keyBase
133 | * key前缀
134 | * @author linchunsen
135 | */
136 | public void loadProperties(Properties properties, String keyBase) {
137 | String delay = properties.getProperty(keyBase+"."+ SERIAL_DELAY_KEY, "" + this.delay);
138 | String timeout = properties.getProperty(keyBase+"."+ SERIAL_TIMEOUT_KEY, "" + this.timeout);
139 | String port = properties.getProperty(keyBase+"."+ SERIAL_PORT_KEY, "" + this.port);
140 | String dataBits = properties.getProperty(keyBase+"."+ SERIAL_DATABITS_KEY, "" + this.dataBits);
141 | String stopBits = properties.getProperty(keyBase+"."+ SERIAL_STOPBITS_KEY, "" + this.stopBits);
142 | String parity = properties.getProperty(keyBase+"."+ SERIAL_PARITY_KEY, "" + this.parity);
143 | String rate = properties.getProperty(keyBase+"."+ SERIAL_RATE_KEY, "" + this.rate);
144 |
145 | this.delay = Integer.parseInt(delay);
146 | this.timeout = Integer.parseInt(timeout);
147 | this.port = port;
148 | this.dataBits = Integer.parseInt(dataBits);
149 | //设置数据位
150 | if (this.dataBits==5) {
151 | this.dataBits=SerialPort.DATABITS_5;
152 | } else if (this.dataBits==6) {
153 | this.dataBits=SerialPort.DATABITS_6;
154 | } else if (this.dataBits==7) {
155 | this.dataBits=SerialPort.DATABITS_7;
156 | } else {
157 | this.dataBits=SerialPort.DATABITS_8;
158 | }
159 | float floatStopBits = Float.parseFloat(stopBits);
160 | //设置停止位
161 | if (floatStopBits==2) {
162 | this.stopBits=SerialPort.STOPBITS_2;
163 | } else if (floatStopBits==1.5) {
164 | this.stopBits=SerialPort.STOPBITS_1_5;
165 | } else {
166 | this.stopBits=SerialPort.STOPBITS_1;
167 | }
168 | this.parity = Integer.parseInt(parity);
169 | //设置校验
170 | if (this.parity==1) {//奇校验
171 | this.parity=SerialPort.PARITY_ODD;
172 | } else if(this.parity==2) {//偶校验
173 | this.parity=SerialPort.PARITY_EVEN;
174 | }else {//无校验
175 | this.parity=SerialPort.PARITY_NONE;
176 | }
177 | this.rate = Integer.parseInt(rate);
178 | }
179 |
180 | public int getDelay() {
181 | return delay;
182 | }
183 |
184 | public void setDelay(int delay) {
185 | this.delay = delay;
186 | }
187 |
188 | public int getTimeout() {
189 | return timeout;
190 | }
191 |
192 | public void setTimeout(int timeout) {
193 | this.timeout = timeout;
194 | }
195 |
196 | public String getPort() {
197 | return port;
198 | }
199 |
200 | public void setPort(String port) {
201 | this.port = port;
202 | }
203 |
204 | public int getDataBits() {
205 | return dataBits;
206 | }
207 |
208 | public void setDataBits(int dataBits) {
209 | this.dataBits = dataBits;
210 | }
211 |
212 | public int getStopBits() {
213 | return stopBits;
214 | }
215 |
216 | public void setStopBits(int stopBits) {
217 | this.stopBits = stopBits;
218 | }
219 |
220 | public int getParity() {
221 | return parity;
222 | }
223 |
224 | public void setParity(int parity) {
225 | this.parity = parity;
226 | }
227 |
228 | public int getRate() {
229 | return rate;
230 | }
231 |
232 | public void setRate(int rate) {
233 | this.rate = rate;
234 | }
235 |
236 | public String getAppName() {
237 | return appName;
238 | }
239 |
240 | public void setAppName(String appName) {
241 | this.appName = appName;
242 | }
243 |
244 | }
245 |
--------------------------------------------------------------------------------
/src/main/java/com/linchunsen/rxtx/SerialPortRxtx.java:
--------------------------------------------------------------------------------
1 | package com.linchunsen.rxtx;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 | import java.util.TooManyListenersException;
7 |
8 | import gnu.io.CommPortIdentifier;
9 | import gnu.io.NoSuchPortException;
10 | import gnu.io.PortInUseException;
11 | import gnu.io.SerialPort;
12 | import gnu.io.SerialPortEventListener;
13 | import gnu.io.UnsupportedCommOperationException;
14 |
15 | /**
16 | *
17 | * 简介
根据串口上下文设置串口配置,并提供启动和关闭的方法
18 | *
19 | *
20 | * 文件修改记录
21 | *
22 | * 修改日期 |
23 | * 修改人 |
24 | * 修改内容 |
25 | *
26 | *
27 | *
28 | * 2017年1月4日 |
29 | * linchunsen |
30 | * 新建文件,并实现基本功能 |
31 | *
32 | *
33 | *
34 | */
35 | public class SerialPortRxtx {
36 | /**
37 | * 标识端口是否已被打开
38 | */
39 | private boolean isOpen;
40 | /**
41 | * 属性描述
42 | */
43 | private CommPortIdentifier portId;
44 | /**
45 | * 属性描述
46 | */
47 | private SerialPort serialPort;
48 | /**
49 | * 输入流
50 | */
51 | private InputStream inputStream;
52 | /**
53 | * 输出流
54 | */
55 | private OutputStream outputStream;
56 | /**
57 | * 串口上下文
58 | */
59 | private SerialContext serialContext;
60 |
61 | public SerialPortRxtx(SerialContext serialContext) {
62 | this.serialContext = serialContext;
63 | }
64 |
65 | /**
66 | * 开启端口 无返回 无参数
67 | *
68 | * @author linchunsen
69 | */
70 | public void open() throws NoSuchPortException, PortInUseException, IOException, TooManyListenersException,
71 | UnsupportedCommOperationException {
72 | portId = CommPortIdentifier.getPortIdentifier(serialContext.getPort());
73 | serialPort = (SerialPort) portId.open(serialContext.getAppName(), serialContext.getTimeout());
74 | inputStream = serialPort.getInputStream();
75 | outputStream = serialPort.getOutputStream();
76 | isOpen = true;
77 | }
78 |
79 | /**
80 | * 关闭端口 无返回 无参数
81 | *
82 | * @author linchunsen
83 | */
84 | public void close() {
85 | if (isOpen) {
86 | try {
87 | serialPort.notifyOnDataAvailable(false);
88 | serialPort.removeEventListener();
89 | inputStream.close();
90 | outputStream.close();
91 | serialPort.close();
92 | isOpen = false;
93 | } catch (IOException ex) {
94 | // "关闭串口失败";
95 | }
96 | }
97 | }
98 |
99 | public boolean isOpen() {
100 | return isOpen;
101 | }
102 |
103 | public void setOpen(boolean isOpen) {
104 | this.isOpen = isOpen;
105 | }
106 |
107 | public SerialContext getSerialContext() {
108 | return serialContext;
109 | }
110 |
111 | public void setSerialContext(SerialContext serialContext) {
112 | this.serialContext = serialContext;
113 | }
114 |
115 | public CommPortIdentifier getPortId() {
116 | return portId;
117 | }
118 |
119 | public void setPortId(CommPortIdentifier portId) {
120 | this.portId = portId;
121 | }
122 |
123 | public SerialPort getSerialPort() {
124 | return serialPort;
125 | }
126 |
127 | public void setSerialPort(SerialPort serialPort) {
128 | this.serialPort = serialPort;
129 | }
130 |
131 | public InputStream getInputStream() {
132 | return inputStream;
133 | }
134 |
135 | public void setInputStream(InputStream inputStream) {
136 | this.inputStream = inputStream;
137 | }
138 |
139 | public OutputStream getOutputStream() {
140 | return outputStream;
141 | }
142 |
143 | public void setOutputStream(OutputStream outputStream) {
144 | this.outputStream = outputStream;
145 | }
146 |
147 | /**
148 | * 为串口设置事件监听器
149 | * 无返回
150 | * @param listener 事件监听器
151 | * @author linchunsen
152 | * @throws TooManyListenersException
153 | * @throws UnsupportedCommOperationException
154 | */
155 | public void addEventListener(SerialPortEventListener listener) throws TooManyListenersException, UnsupportedCommOperationException {
156 | if (isOpen) {
157 | this.serialPort.removeEventListener();
158 | this.serialPort.addEventListener(listener);
159 | serialPort.notifyOnDataAvailable(true);
160 | serialPort.setSerialPortParams(
161 | serialContext.getRate(),
162 | serialContext.getDataBits(),
163 | serialContext.getStopBits(),
164 | serialContext.getParity());
165 | }else {
166 | throw new RuntimeException("串口未打开,请检查是否执行了open()方法");
167 | }
168 | }
169 |
170 | }
171 |
--------------------------------------------------------------------------------
/src/main/java/com/linchunsen/rxtx/SerialReader.java:
--------------------------------------------------------------------------------
1 | package com.linchunsen.rxtx;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 | import java.util.TooManyListenersException;
7 |
8 | import gnu.io.NoSuchPortException;
9 | import gnu.io.PortInUseException;
10 | import gnu.io.SerialPortEventListener;
11 | import gnu.io.UnsupportedCommOperationException;
12 |
13 | /**
14 | *
15 | * 简介
串口通讯的常规读取器
16 | *
17 | *
18 | * 文件修改记录
19 | *
20 | * 修改日期 |
21 | * 修改人 |
22 | * 修改内容 |
23 | *
24 | *
25 | *
26 | * 2016年12月29日 |
27 | * linchunsen |
28 | * 新建文件,并实现基本功能 |
29 | *
30 | *
31 | *
32 | */
33 | public class SerialReader {
34 |
35 | private SerialContext serialContext;
36 | private MessageParseAble messageParse;
37 |
38 | /**
39 | * 根据传入的串口配置上下文和报文解析器来构建报文读取器
40 | *
41 | * @param serialContext
42 | * 串口配置上下文
43 | * @param messageParse
44 | * 报文解析器
45 | */
46 | public SerialReader(SerialContext serialContext, MessageParseAble messageParse) {
47 | super();
48 | this.serialContext = serialContext;
49 | this.messageParse = messageParse;
50 | }
51 |
52 | /**
53 | * 启动串口的读监听器 无返回 无参数
54 | *
55 | * @author linchunsen
56 | * @throws UnsupportedCommOperationException
57 | * @throws TooManyListenersException
58 | * @throws IOException
59 | * @throws PortInUseException
60 | * @throws NoSuchPortException
61 | */
62 | public void startReaderListener() throws NoSuchPortException, PortInUseException, IOException, TooManyListenersException, UnsupportedCommOperationException {
63 | SerialPortRxtx serialPortRxtx = new SerialPortRxtx(this.serialContext);
64 | serialPortRxtx.open();
65 | SerialPortEventListener listener = new SerialAbstarctListener(serialPortRxtx) {
66 |
67 | private byte[] datas = new byte[1024];
68 |
69 | @Override
70 | public void readerAndWriter(InputStream inputStream, OutputStream outputStream) {
71 | try {
72 | if (inputStream.available() > 0) {
73 | int size = inputStream.read(datas);
74 | StringBuilder dataBuilder = new StringBuilder();
75 | String iString;
76 | for (int i = 0; i < size; i++) {
77 | iString = Integer.toHexString(datas[i] & 0xFF);
78 | if (iString.length() == 1) {
79 | iString = "0" + iString;
80 | }
81 | dataBuilder.append(iString);
82 | }
83 | String message = dataBuilder.toString().toUpperCase();
84 | messageParse.messageParse(message);
85 | }
86 | } catch (IOException e) {
87 | // TODO Auto-generated catch block
88 | e.printStackTrace();
89 | } catch (Exception e) {
90 | // TODO Auto-generated catch block
91 | e.printStackTrace();
92 | }
93 | }
94 | };
95 | serialPortRxtx.addEventListener(listener);
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/com/linchunsen/rxtx/SerialStarter.java:
--------------------------------------------------------------------------------
1 | package com.linchunsen.rxtx;
2 |
3 | import java.util.List;
4 | import java.io.IOException;
5 | import java.util.ArrayList;
6 | import java.util.HashSet;
7 | import java.util.Properties;
8 | import java.util.Set;
9 | import java.util.TooManyListenersException;
10 |
11 | import gnu.io.NoSuchPortException;
12 | import gnu.io.PortInUseException;
13 | import gnu.io.UnsupportedCommOperationException;
14 |
15 | /**
16 | *
17 | * 简介
串口通讯的启动类
18 | *
19 | *
20 | * 文件修改记录
21 | *
22 | * 修改日期 |
23 | * 修改人 |
24 | * 修改内容 |
25 | *
26 | *
27 | *
28 | * 2016年12月29日 |
29 | * linchunsen |
30 | * 新建文件,并实现基本功能 |
31 | *
32 | *
33 | *
34 | */
35 | public class SerialStarter {
36 |
37 | private Properties properties;
38 |
39 | /**
40 | * 根据传入的系统配置来定义串口通讯的启动类
41 | */
42 | public SerialStarter(Properties properties) {
43 | super();
44 | this.properties = properties;
45 | }
46 |
47 | private List serialWriters = null;
48 |
49 | /**
50 | * 将传入的消息逐次发给各个串口
51 | * @throws IOException
52 | * @throws UnsupportedCommOperationException
53 | * @throws TooManyListenersException
54 | * @throws PortInUseException
55 | * @throws NoSuchPortException
56 | */
57 | public void wirte(String message) throws IOException, NoSuchPortException, PortInUseException, TooManyListenersException, UnsupportedCommOperationException {
58 | //如果写串口器列表还未初始化,则初始化
59 | if (serialWriters == null) {
60 | serialWriters = new ArrayList<>();
61 | Set