java串口通讯


package com.itek.serial;

/**
 * createtime : 2018年6月1日 上午9:47:36
 */
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.TooManyListenersException;

import com.itek.utils.DateUtils;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

/**
 * TODO
 * 
 * @author XWF
 */

public final class RXTXtest {

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // 获得系统端口列表
        getSystemPort();
        // 开启端口COM2,波特率9600
        final SerialPort serialPort = openSerialPort("COM2", 9600);
        // 启动一个线程每2s向串口发送数据,发送1000次hello
        new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 1;
                while (i < 1000) {
                    String s = "hello";
                    byte[] bytes = s.getBytes();
                    RXTXtest.sendData(serialPort, bytes);// 发送数据
                    i++;
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        // 设置串口的listener
        RXTXtest.setListenerToSerialPort(serialPort, new SerialPortEventListener() {
            @Override
            public void serialEvent(SerialPortEvent arg0) {

                // byte[] bytes2=readFromPort(serialPort);
                // System.out.println("dddddddd:" + new String(bytes2));
                if (arg0.getEventType() == SerialPortEvent.DATA_AVAILABLE) {// 数据通知
                    byte[] bytes = RXTXtest.readData(serialPort);
                    System.out.println("收到的数据长度:" + bytes.length);
                    System.out.println("收到的数据:" + new String(bytes));
                }
            }
        });
        // closeSerialPort(serialPort);
    }

    /**
     * 获得系统可用的端口名称列表
     * 
     * @return 可用端口名称列表
     */
    @SuppressWarnings("unchecked")
    public static List getSystemPort() {
        List systemPorts = new ArrayList<>();
        // 获得系统可用的端口
        Enumeration portList = CommPortIdentifier.getPortIdentifiers();
        while (portList.hasMoreElements()) {
            String portName = portList.nextElement().getName();// 获得端口的名字
            systemPorts.add(portName);
        }
        System.out.println("canuse   serialport:" + systemPorts);
        return systemPorts;
    }

    /**
     * 开启串口
     * 
     * @param serialPortName 串口名称
     * @param baudRate       波特率
     * @return 串口对象
     * @throws Exception
     */
    public static SerialPort openSerialPort(String serialPortName, int baudRate) throws Exception {

        // 通过端口名称得到端口
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(serialPortName);
        // 打开端口,(自定义名字,打开超时时间)
        CommPort commPort = portIdentifier.open(serialPortName, 2222);
        // 判断是不是串口
        if (commPort instanceof SerialPort) {
            SerialPort serialPort = (SerialPort) commPort;
            // 设置串口参数(波特率,数据位8,停止位1,校验位无)
            serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);
            serialPort.setInputBufferSize(1024);
            serialPort.setOutputBufferSize(1024);
            System.out.println("开启串口成功,串口名称:" + serialPortName);
            return serialPort;
        } else {
            // 是其他类型的端口
            throw new NoSuchPortException();
        }

    }

    /**
     * 关闭串口
     * 
     * @param serialPort 要关闭的串口对象
     */
    public static void closeSerialPort(SerialPort serialPort) {
        if (serialPort != null) {
            serialPort.close();
            System.out.println("关闭了串口:" + serialPort.getName());
            serialPort = null;
        }
    }

    /**
     * 向串口发送数据
     * 
     * @param serialPort 串口对象
     * @param data       发送的数据
     */
    public static void sendData(SerialPort serialPort, byte[] data) {
         System.out.println(" send before------");
        OutputStream os = null;
        try {
            os = serialPort.getOutputStream();// 获得串口的输出流
            os.write(data);
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                    os = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
         System.out.println(" send after------");
    }

    /**
     * 从串口读取数据
     * 
     * @param serialPort 要读取的串口
     * @return 读取的数据
     */
    public static byte[] readData(SerialPort serialPort) {
        InputStream is = null;
        byte[] alltytes = new byte[0];
        byte[] bytes = null;
        try {
            is = serialPort.getInputStream();// 获得串口的输入流
            int bufflenth = is.available();// 获得数据长度
            while (bufflenth != 0) {
                bytes = new byte[bufflenth];// 初始化byte数组
                is.read(bytes);
                // System.out.println(DateUtils.getCurrentDateTime_SSS()+" bytes leng
                // ---"+bytes.length);
                alltytes = byteMerger(alltytes, bytes);
                Thread.sleep(50);
                bufflenth = is.available();
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        // System.out.println("alltytes leng ---"+alltytes.length);
        return alltytes;
    }

    public static byte[] byteMerger(byte[] bt1, byte[] bt2) {
        byte[] bt3 = new byte[bt1.length + bt2.length];
        System.arraycopy(bt1, 0, bt3, 0, bt1.length);
        System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
        return bt3;
    }

    /**
     * 给串口设置监听
     * 
     * @param serialPort
     * @param listener
     */
    public static void setListenerToSerialPort(SerialPort serialPort, SerialPortEventListener listener) {
        try {
            // 给串口添加事件监听
            serialPort.addEventListener(listener);
        } catch (TooManyListenersException e) {
            e.printStackTrace();
        }
        serialPort.notifyOnDataAvailable(true);// 串口有数据监听
        serialPort.notifyOnBreakInterrupt(true);// 中断事件监听
    }

}
package com.itek.serial;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.itek.IDCPowerMain;
import com.itek.agreement.SuperSerial;
import com.itek.constant.SysConstant;
import com.itek.utils.Convert;
import com.itek.utils.ConvertUtil;
import com.itek.utils.DateUtils;

import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

public class EquSerial {
	private final static Logger logger = LoggerFactory.getLogger(EquSerial.class);
	public static SerialPort serialPort = null;
	public static String data = "";
	public static InputStream inputStream = null;
	public static OutputStream outputStream = null;
	public static BufferedWriter bWriter = null;
	public static long lastsendtime = 0;
	public static Boolean sendisreturn = true;

	public static void linsen() {
		RXTXtest.setListenerToSerialPort(serialPort, new SerialPortEventListener() {
			@Override
			public void serialEvent(SerialPortEvent arg0) {

				if (arg0.getEventType() == SerialPortEvent.DATA_AVAILABLE) {// 数据通知
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					byte[] bytes = readData();
					String recive = Convert.byte2HexStrNoSpace(bytes, 0, bytes.length);
					// data = data + recive;

					// System.out.println(DateUtils.getCurrentDateTime_SSS() + " received serial
					// msg:" + recive);
					// System.out.println("data:" + data);
					// 处理收到的消息

					IDCPowerMain.threadPool.execute(new Runnable() {

						@Override
						public void run() {
							SuperSerial.handle(recive.toUpperCase());
						}
					});

				}
			}

		});

	}

	public static void openport(String port, int bps) {
		closeport();
		try {
			serialPort = RXTXtest.openSerialPort(port, bps);
			DateUtils.sleep(500);
			inputStream = serialPort.getInputStream();// 获得串口的输入流
			outputStream = serialPort.getOutputStream();// 获得串口的输出流
			bWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
			linsen();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.toString());
		}

	}

	public static void closeport() {
		if (serialPort != null) {
			serialPort.close();
			serialPort.removeEventListener();
			serialPort = null;
		}
		if (outputStream != null) {
			try {
				outputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			outputStream = null;
		}
		if (inputStream != null) {
			try {
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			inputStream = null;
		}
	}

	public static void senddata(String data) {
		Lock lock = new ReentrantLock();
		lock.lock();
		try {
			// logger.info(DateUtils.getCurrentDateTime_SSS() + "send:" + data);
			byte[] bytes = ConvertUtil.str2_2Bytes(data);
			if (serialPort == null || outputStream == null) {
				openport(SysConstant.Serialport485, SysConstant.baudRate485);
			}
			outputStream.write(bytes);
			outputStream.flush();
			lastsendtime = System.currentTimeMillis();
		} catch (Exception e) {
			logger.error(e.toString());
		} finally {
			lock.unlock();
		}

	}

	public static byte[] readData() {
		if (serialPort == null || inputStream == null) {
			openport(SysConstant.Serialport485, SysConstant.baudRate485);
		}

		byte[] alltytes = new byte[0];
		byte[] bytes = null;
		try {
			int bufflenth = inputStream.available();// 获得数据长度
			while (bufflenth != 0) {
				bytes = new byte[bufflenth];// 初始化byte数组
				inputStream.read(bytes);
				alltytes = RXTXtest.byteMerger(alltytes, bytes);
				Thread.sleep(20);
				bufflenth = inputStream.available();
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.toString());
		}
		return alltytes;
	}

	public static void main(String args[]) {

	}
}