创建一个单独的线程来从java中的双向串行端口读取

时间:2016-10-18 16:02:48

标签: java multithreading

我想从串口读取数据,为此我需要一个单独的线程,它将在后台运行并不断检查数据是否可以读取,进一步的串口是双向(rx-tx)。一种方法是添加一个串行事件监听器,但我没有得到如何使后台线程做同样的事情,请帮助我!

我做了一个类读取,它接受来自其他类的输入流,我正在创建这个读类的一个线程,以便它在后台运行,看看是否有任何接收事件被触发,但接收是不是&# 39;发生了什么,问题是什么,有人吗?

import java.io.IOException;
import java.io.InputStream; 
import java.util.TooManyListenersException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;


public class read implements SerialPortEventListener, Runnable {

InputStream inputStream;
SerialPort sp;
public read(SerialPort sp, InputStream input){

    inputStream = input;
    this.sp = sp;
    try {
        sp.addEventListener(this);
} catch (TooManyListenersException e) {System.out.println(e);}
    sp.notifyOnDataAvailable(true);
/*    try{
        sp.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
    }
    catch(Exception e){}*/

        new Thread(this).start();

}

@Override
    public void run() {
    try {
        Thread.sleep(20000);
    } catch (InterruptedException e) {System.out.println(e);}
}
@Override
public void serialEvent(SerialPortEvent event) {
    switch(event.getEventType()) {
    case SerialPortEvent.BI:
    case SerialPortEvent.OE:
    case SerialPortEvent.FE:
    case SerialPortEvent.PE:
    case SerialPortEvent.CD:
    case SerialPortEvent.CTS:
    case SerialPortEvent.DSR:
    case SerialPortEvent.RI:
    case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
        break;
    case SerialPortEvent.DATA_AVAILABLE:
        byte[] readBuffer = new byte[1000];

        try {
            while (true) {

                int numBytes;
                if(inputStream.available() > 0){

                    numBytes = inputStream.read(readBuffer);

                }
                else
                    break;

            }
             System.out.print(new String(readBuffer));
             try{
    inputStream.close();
    sp.close();
    }
    catch(Exception e){}
        } catch (IOException e) {System.out.println(e);}
        break;
    }
}
}

1 个答案:

答案 0 :(得分:1)

  

我想从串口读取数据,为此我需要一个单独的线程,它将在后台运行并不断检查数据是否可以读取'

不,你没有。你需要一个倾听者。你已经有了一个倾听者。您已将其添加到串行端口。你不需要任何其他东西。您不需要将侦听器作为线程启动。它是JavaComm将自动调用的回调对象。

  

此外串口是双向的(rx-tx)。一种方法是添加一个串行事件监听器,但我没有得到如何使后台线程做同样的事情...

那是因为你不必这样做。你误解了听众的工作方式。当侦听器触发时,执行适当的回调方法中的代码。就是这样。您无需线程。

  

我做了一个类读取,它从一些其他类

获取输入流

正确。

  

我正在制作这个读类的一个线程,以便它在后台运行以查看是否有任何接收事件被触发

不必要且毫无意义,见上文。

  

但接收没有发生,问题是什么,有人吗?

你做错了。删除线程,删除run()方法,删除start(),然后等待事件传递给回调方法。

重新编写代码:

case SerialPortEvent.DATA_AVAILABLE:
    byte[] readBuffer = new byte[1000];

    try {
        while (true) {

删除循环。

            int numBytes;
            if(inputStream.available() > 0){

删除测试。这已经成为现实,case SerialPortEvent.DATA_AVAILABLE意味着什么。

                numBytes = inputStream.read(readBuffer);
            }
            else
                break;

删除此elsebreak

         System.out.print(new String(readBuffer));

更改为

         System.out.print(new String(readBuffer, 0, numBytes));

您忽略了read()返回的长度,因此您需要在缓冲区末尾构建一个String垃圾,而不是读取的内容。

         try{
inputStream.close();
sp.close();
}

删除所有这些。您不应该因为目前没有可读取的数据而关闭输入流。保持开放。目前,您正在关闭流,因此在第一个数据到达后禁用侦听器。