java基于rxtx串口操作

一、rxtx串口操作

package com.am.cs12.commu.remote_serialPort;

import java.util.*;
import java.io.*;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import com.am.util.NumberUtil;

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

import com.am.cs12.config.*;


public class SerialPortChannel  implements SerialPortEventListener  {

    private static Logger log = Logger.getLogger(SerialPortChannel.class) ;

    private SerialPort serialPort;
    private SerialPortVO configVO ;
    private String appName ;
    private int getPortDelay ;

    /**
     * 构造方法
     * @param configVO 串口参数配置
     * @param appName 就用程序名称
     * @param getPortDelay 得到串口前及循环得到串口时的延迟时长(CommPortIdentifier原码中,每次最小延迟200毫秒)
     */
    public SerialPortChannel(SerialPortVO configVO , String appName, int getPortDelay) {
        this.configVO = configVO ;
        this.appName = appName ;
        this.getPortDelay = getPortDelay ;
    }

    /**
     * 向串口中写数据
     * @param bytes
     */
    public void write(byte[] bytes) {
        OutputStream os = null ;
        try {
            os = serialPort.getOutputStream();
            if(os == null){
                log.error("从串口(" + this.configVO.getName() + ")中得到输出流出错");
                return ;
            }
            if (Level.INFO.isGreaterOrEqual(log.getEffectiveLevel())) {
                try {
                    String hex = NumberUtil.byte2Hex(bytes);
                    log.info("从串口(" + this.configVO.getName() + ")输出数据:\n" + hex);
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
            }
            os.write(bytes);
        } catch (IOException e) {
            log.error("向串口(" + this.configVO.getName() + ")中写入数据发生异常!") ;
        }finally{
            if(os != null){
                try{
                    os.close() ;
                }catch(Exception e){
                    log.error("关闭串口(" + this.configVO.getName() + ")输出流出错!") ;
                }
            }
        }
    }




    /**
     * 从串口中读数据
     * @return
     */
    @SuppressWarnings("finally")
    public byte[] read() {
        byte[] bytes = null;
        InputStream is = null ;
        try {
            is = serialPort.getInputStream();

            if(is == null) {
                log.error("从串口(" + this.configVO.getName() + ")中得到输入流出错!") ;
                return null ;
            }
            ArrayList<byte[]> list = new ArrayList<byte[]>();
            int count = 0 ;
            int total = 0 ;
            while (is.available() > 0) {
                byte[] b = new byte[is.available()] ;
                total += is.read(b);
                list.add(count++ , b) ;
                try {
                    Thread.sleep(configVO.getWaitTime());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally{
                    continue ;
                }
            }


            if (list.size() > 0) {
                // 说明读进来数据了
                bytes = new byte[total];
                Iterator<byte[]> it = list.iterator();
                byte[] b = null ;
                int num = 0 ;
                while (it.hasNext()) {
                    b = it.next();
                    System.arraycopy(b, 0, bytes, num, b.length);
                    num += b.length;
                }
            }





            log.info("从串口(" + this.configVO.getName() + ")中经" + count + "次循环,读得"+total+"字节数据。");

            if (bytes != null && bytes.length > 0) {
                if (Level.INFO.isGreaterOrEqual(log.getEffectiveLevel())) {
                    try {
                        String hex = NumberUtil.byte2Hex(bytes);
                        log.info("从串口(" + this.configVO.getName() + ")中读得数据:" + hex);
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    }
                }
            }
            new SerialPortHandle().receiveData(this.configVO.getId() , bytes);

            return bytes ;
        } catch (IOException e) {
            log.error("从串口(" + this.configVO.getName() + ")中读取数据发生异常!" , e) ;
        }finally{
            if(is != null){
                try{
                    is.close() ;
                }catch(Exception e){
                    log.error("关闭串口(" + this.configVO.getName() + ")输入流出错!") ;
                }
            }
        }
        return null;
    }

    /**
     * 打开串口
     * @param porter
     */
    public boolean openPort(){
        if(this.configVO.getDebugForNoTerminal()){
            System.out.println("!!串口(" + this.configVO.getName() + ")通信服务(ID:" + appName + ")无终端设备模拟启动");
            return true ;
        }
        try {
            CommPortIdentifier porter = CommPortIdentifier.getPortIdentifier(this.configVO.getName());
            if (porter == null) {
                log.error("不能得到串口" + this.configVO.getName()) ;
                return false ;
            }
            if (porter.getPortType() != CommPortIdentifier.PORT_SERIAL) {
                log.error("得到的通信接口不是串口!") ;
                return false ;
            }
            this.serialPort = (SerialPort)porter.open(this.appName, this.getPortDelay);
            this.serialPort.setSerialPortParams(this.configVO.getBaudrate(), this.configVO.getDataBits(), this.configVO.getStopBits(), this.configVO.getParity());

            this.serialPort.addEventListener(this) ;

            // Set notifyOnDataAvailable to true to allow event driven input.
            this.serialPort.notifyOnDataAvailable(true);

            // Set notifyOnBreakInterrup to allow event driven break handling.
            this.serialPort.notifyOnBreakInterrupt(true);

            this.serialPort.notifyOnCTS(true);
            this.serialPort.notifyOnDSR(true);
            this.serialPort.notifyOnRingIndicator(true);
            this.serialPort.notifyOnCarrierDetect(true);
            this.serialPort.notifyOnOverrunError(true);
            this.serialPort.notifyOnParityError(true);
            this.serialPort.notifyOnFramingError(true);
            this.serialPort.notifyOnOutputEmpty(true);

        } catch (PortInUseException ex) {
            this.serialPort = null;
            ex.printStackTrace();
        } catch (NoSuchPortException ex) {
            this.serialPort = null;
            ex.printStackTrace();
        } catch (Exception ex){
            this.serialPort = null ;
            ex.printStackTrace();
        }
        if (this.serialPort == null) {
            return false ;
        }
        return true ;
    }

    /**
     * 事件监听方法
     */
    public void serialEvent(SerialPortEvent evt) {
        log.info(this.configVO.getName() + "有事件到来!");
        switch (evt.getEventType()) {
        case SerialPortEvent.CTS:
            log.info(this.configVO.getName() + "清除发送.");
            break;
        case SerialPortEvent.CD:
            log.info(this.configVO.getName() + "载波检测.");
            break;
        case SerialPortEvent.BI:
            log.error(this.configVO.getName() + "通讯中断.");
            break;
        case SerialPortEvent.DSR:
            log.info(this.configVO.getName() + "数据设备准备好.");
            break;
        case SerialPortEvent.FE:
            log.error(this.configVO.getName() + "帧错误.");
            break;
        case SerialPortEvent.OE:
            log.error(this.configVO.getName() + "溢位错误.");
            break;
        case SerialPortEvent.PE:
            log.error(this.configVO.getName() + "奇偶校验错.");
            break;
        case SerialPortEvent.RI:
            log.info(this.configVO.getName() + "振铃指示.");
            break;
        case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
            log.info(this.configVO.getName() + "输出缓冲区已清空.");
            break;
        case SerialPortEvent.DATA_AVAILABLE:
            log.info(this.configVO.getName() + "有数据到达.");
            this.read();
            break;
        }
    }
}

二、rxtx读取串口列表


package com.am.cs12.util;

import java.lang.reflect.Method;
import java.util.*;

import gnu.io.CommPortIdentifier;


public class FindCom {  

    static private Class<?> classCommPortIdentifier;
    static {
        try {
            classCommPortIdentifier = Class.forName("gnu.io.CommPortIdentifier");//"javax.comm.CommPortIdentifier");
        } catch (ClassNotFoundException e1) {
            throw new RuntimeException("出错,CommPortIdentifier类未发现!");
        }
    }

    /**
     * 发现串口
     * @return
     */
    private static Enumeration<CommPortIdentifier> getPortIdentifiers() {
        if (classCommPortIdentifier == null) {
            throw new RuntimeException("出错,CommPortIdentifier类未发现!");
        }
        Enumeration<CommPortIdentifier> list;
        try {
            // get the enumeration of real objects
            Method method = classCommPortIdentifier.getMethod("getPortIdentifiers", (java.lang.Class[]) null);
            CommPortIdentifier type = null;
            list = invokeAndCastEnumeration(type, method, null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // wrap the real objects
        Vector<CommPortIdentifier> vec = new Vector<CommPortIdentifier>();
        while (list.hasMoreElements()){
            vec.add(list.nextElement());
        }
        return vec.elements();
    }
    @SuppressWarnings( { "unchecked" })
    public static <T> Enumeration<T> invokeAndCastEnumeration(T returnType,
            Method m, Object obj, Object... args) {
        try {
            return (Enumeration<T>) m.invoke(obj, args);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 发现串口
     * @return
     */
    public List<String> find(){
        List<String> coms = new ArrayList<String>() ;
        Enumeration<CommPortIdentifier> portList = getPortIdentifiers();
        while (portList.hasMoreElements()) {
            CommPortIdentifier portId = portList.nextElement();
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                coms.add(portId.getName());
            }
        }
        return coms ;
    }

    public static void main(String args[]) {
        FindCom o = new FindCom();
        List<String> list = o.find();
        if(list != null){
            Iterator<String> it = list.iterator() ;
            while(it.hasNext()){
                System.out.println(it.next()) ;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值