在java中创建一个单独的线程来读取双向串行端口
我想从串行端口读取数据,为此我需要一个单独的线程,该线程将在后台运行,并不断检查“是否可以读取数据”,此外,串行端口是双向的(rx tx)。一种方法是添加一个串行事件监听器,但我不知道如何制作一个后台线程来做同样的事情,请帮助我 我已经创建了一个类read,它从其他类获取一个输入流,我正在创建这个read类的一个线程,以便它在后台运行,查看是否触发了任何receive事件,但是没有发生receive,有什么问题吗在java中创建一个单独的线程来读取双向串行端口,java,multithreading,Java,Multithreading,我想从串行端口读取数据,为此我需要一个单独的线程,该线程将在后台运行,并不断检查“是否可以读取数据”,此外,串行端口是双向的(rx tx)。一种方法是添加一个串行事件监听器,但我不知道如何制作一个后台线程来做同样的事情,请帮助我 我已经创建了一个类read,它从其他类获取一个输入流,我正在创建这个read类的一个线程,以便它在后台运行,查看是否触发了任何receive事件,但是没有发生receive,有什么问题吗 import java.io.IOException; import java.i
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;
}
}
}
我想从串行端口读取数据,为此我需要一个单独的线程,该线程将在后台运行,并不断检查“数据是否可读取”
不,你没有。你需要一个倾听者。你已经有了一个听众。您已将其添加到串行端口。你不需要其他任何东西。您不需要将侦听器作为线程启动。它是JavaComm将自动调用的回调对象
此外,串行端口为双向(rx-tx)。一种方法是添加一个串行事件监听器,但我不知道如何使后台线程也这样做
那是因为你不必这么做。你误解了听众的工作方式。当侦听器激发时,将执行相应回调方法中的代码。就这样。您的部件不需要螺纹
我已经读了一个类,它从其他类获取一个输入流
对
我正在为这个read类创建一个线程,以便它在后台运行,查看是否触发了任何receive事件
不必要和无意义,见上文
但是收信没有发生,有什么问题吗
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;
}
}
}
你做错了。删除线程,删除run()
方法,删除start()
,然后等待事件传递到回调方法
你的代码是:
case SerialPortEvent.DATA_AVAILABLE:
byte[] readBuffer = new byte[1000];
try {
while (true) {
拆下回路
int numBytes;
if(inputStream.available() > 0){
删除测试。这已经是事实,这就是可用数据的含义
numBytes = inputStream.read(readBuffer);
}
else
break;
删除此else
和break
System.out.print(new String(readBuffer));
改为
System.out.print(new String(readBuffer, 0, numBytes));
您忽略了read()
返回的长度,因此您正在构造一个字符串
,该字符串在缓冲区的末尾包含超出读取范围的垃圾
try{
inputStream.close();
sp.close();
}
移除所有这些。您不应该仅仅因为当前没有可读取的数据就关闭输入流。让它开着。目前,在第一条数据到达后,您正在关闭流,从而禁用侦听器。请分享您的尝试。在这里,我更新了问题,看看您的Runnable什么都没做。事实上,线程将休眠20秒,然后它就死了。