Java RXTX串行连接-阻塞读取()的问题

Java RXTX串行连接-阻塞读取()的问题,java,serial-port,rxtx,Java,Serial Port,Rxtx,我试图使用RXTX库来阻止Windows(XP和7)上的串行通信。我已经在两端测试了与超级终端的连接,它工作得完美无缺 我使用以下代码建立了连接:(为了清晰起见,省略了异常处理和防御检查) 当我使用 outWriter.println("test message"); flush(); 消息在另一端接收良好,但正在呼叫 inReader.readLine() 即时返回“java.io.IOException:底层输入流返回零字节” 然后,我决定尝试实现自己的阻塞读取逻辑,并编写了以下代码:

我试图使用RXTX库来阻止Windows(XP和7)上的串行通信。我已经在两端测试了与超级终端的连接,它工作得完美无缺

我使用以下代码建立了连接:(为了清晰起见,省略了异常处理和防御检查)

当我使用

outWriter.println("test message");
flush();
消息在另一端接收良好,但正在呼叫

inReader.readLine()
即时返回“java.io.IOException:底层输入流返回零字节”

然后,我决定尝试实现自己的阻塞读取逻辑,并编写了以下代码:

public String readLine() throws IOException {        
    String line = new String();
    byte[] nextByte = {-1};
    while (true) {
        nextByte[0] = (byte)inStream.read();
        logger.debug("int read: " + nextByte[0]);
        if (nextByte[0] == (byte)-1) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            continue;
        }
        logger.debug("byte read: " + nextByte[0]);

        line = line + new String(nextByte);
        if (nextByte[0] == (byte)13) {  // 13 is carriage return in ASCII
            return line;
        }
    }
}
但是这段代码在一个无限循环中运行,“nextByte[0]=(byte)inStream.read();”分配-1,无论通过串行连接发送什么。另外,另一端口吃得很厉害,只允许我每隔1-3秒发送一个字符。如果我尝试在短时间内发送多个字符,则会挂起很长时间

非常感谢您的帮助

*编辑-使用inStream.read(nextByte)而不是“nextByte[0]=(byte)inStream.read();”不会写入nextByte变量,无论我通过串行连接向它发送什么


*edit2-由于我的代码与SUN javax.comm lib和我从朋友那里得到的win32com.dll完美地结合在一起,我已经停止了使用RXTX的尝试。我对解除通信阻塞不感兴趣,这似乎是其他人让RXTX工作的唯一方式。

我认为您在自己的readLine实现中编写的代码有缺陷。读取第一个字符后,nextByte[0]永远不会恢复为-1。 您应该尝试使用inStream.read(nextByte)返回的值来表示从流中读取的字节数,而不是字节数组的值

无论如何,我认为您应该使用基于事件的方法,使用SerialPortEventListener读取输入:

serialPort.addEventListener(new SerialPortEventListener() {

      public void serialEvent(SerialPortEvent evt) {
           switch (evt.getEventType()) {
           case SerialPortEvent.DATA_AVAILABLE:
               dataReceived();
               break;
           default:
               break;
           }
      }
});
serialPort.notifyOnDataAvailable(true);

使用RXTX-2.2pre2,以前的版本有一个错误,它阻止阻塞I/O正常工作

不要忘记将端口设置为阻塞模式:

serialPort.disableReceiveTimeout();
serialPort.enableReceiveThreshold(1);

它可能没有阻塞,但当流为空时,只需捕获IOE并继续从中读取。这就是我使用RXTX-2.1-7所做的,它工作正常,我使用它来读写arduino:

public static class SerialReader implements Runnable {
    InputStream in;
    public SerialReader(InputStream in) {
        this.in = in;
    }
    public void run() {
        Boolean keepRunning = true;
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String line;
        while (keepRunning) {
            try {
                while ((line = br.readLine()) != null) {
                  //DO YOUR STUFF HERE
                }
            } catch (IOException e) {
                try {
                    //ignore it, the stream is temporarily empty,RXTX's just whining
                    Thread.sleep(200);
                } catch (InterruptedException ex) {
                    // something interrupted our sleep, exit ...
                    keepRunning = false;
                }
            }
        }
    }
}
我已经这样解决了

try 
        {
            if(input.ready()==true)
            {
            String inputLine=input.readLine();
            System.out.println(inputLine);
            }

        } catch (Exception e) 

*编辑-进一步调试表明,无论通过串行连接发送什么,inStream.read(nextByte)都不会写入nextByte变量。可能重复@Peter Knego-是的,它看起来相关,但我对他试图实现的多线程解锁行为不感兴趣。嗨,Svante。我也在努力解决同样的问题。你从哪里得到了win32com.dll&javax.comm。请你指导我。谢谢你的建议。我试图用RXTX交换SUN(或Oracle)javax.comm包和朋友发送的win32com.dll。我的代码现在工作完美无瑕。所以我会坚持下去。太糟糕了,我听到了TXRX的好消息,但是当他们的InputStream实现不支持阻塞行为的承诺时,我就没有什么可以使用它了。我不认为问题来自RXTX本身,但更具体地说是您的配置。无论如何,如果javax.comm能够满足您在跨平台使用和部署方面的需求,那就太好了!嗨,斯凡特。我也在为同样的问题而挣扎。你从哪里得到了win32com.dll和javax.comm。你能给我指点一下吗。在里面放一个错误计数器明智吗?例如,如果您连续三次、十次或一百次获得相同的
IOException
,您不应该忽略它吗?否则,当出现合法错误时,您可能会遇到一个尴尬的循环。
try 
        {
            if(input.ready()==true)
            {
            String inputLine=input.readLine();
            System.out.println(inputLine);
            }

        } catch (Exception e)