RXTX serial connection - issue with blocking read()

馋奶兔 提交于 2019-11-30 00:07:32

问题


I am trying to use the RXTX library for blocking serial communication on Windows (XP and 7). I have tested the connection with Hyperterminal in both ends, and it works flawlessly.

I set up the connection with the following code: (exception handling and defensive checks omitted for clarity)

private InputStream inStream;
private OutputStream outStream;
private BufferedReader inReader;
private PrintWriter outWriter;
private SerialPort serialPort;
private final String serialPortName;

public StreamComSerial(String serialPortName) {
this.serialPortName = serialPortName;
CommPortIdentifier portIdentifier;
portIdentifier = CommPortIdentifier.getPortIdentifier(serialPortName);
CommPort commPort = null;
commPort = portIdentifier.open(this.getClass().getName(),500);
serialPort = (SerialPort) commPort;    serialPort.setSerialPortParams(4800,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
inStream = serialPort.getInputStream();
outStream = serialPort.getOutputStream();
inReader = new BufferedReader(new InputStreamReader(inStream, Settings.getCharset()));
outWriter = new PrintWriter(new OutputStreamWriter(outStream, Settings.getCharset()));

When I use

outWriter.println("test message");
flush();

the message is recieved fine on the other end, but calling

inReader.readLine()

imidiately returns "java.io.IOException: Underlying input stream returned zero bytes".

I then decided to try and implement my own blocking read logic and wrote this:

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;
        }
    }
}

But this code goes in an infinite loop and "nextByte[0] = (byte)inStream.read();" assigns -1 no matter what is sent over the serial connection. In addition, the other end stutters quite badly and only lets me send a character every 1-3 sec. and hangs for a long time if I try to send many characters in a short burst.

Any help very appreciated.

*edit - using inStream.read(nextByte) instead of "nextByte[0] = (byte)inStream.read();" does not write to the nextByte variable, no matter what I send to it through the serial connection.

*edit2 - as my code works flawlessly with the SUN javax.comm lib and a win32com.dll I got from a friend, I have ceased trying to make it work with RXTX. I am not interested in unblocking communication, which seems to be the only way other people can make RXTX work.


回答1:


Use RXTX-2.2pre2, previous versions have had a bug which prevented blocking I/O from working correctly.

And do not forget to set port to blocking mode:

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



回答2:


I think the code you wrote in your own readLine implementation is buggy. nextByte[0] is never restored to -1 after the first character is read. You should try to use the value returned by inStream.read(nextByte) to state the number of bytes read from the stream instead of the value of your byte array.

Anyway I think you should go for an event based method of reading the inputs with a SerialPortEventListener:

serialPort.addEventListener(new SerialPortEventListener() {

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



回答3:


it may not be blocking but when the stream is empty, just catch the IOE and keep reading from it. This is what I do with RXTX-2.1-7 and it works fine, I use it to read and write to an 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;
                }
            }
        }
    }
}



回答4:


I have solved this way

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

        } catch (Exception e) 


来源:https://stackoverflow.com/questions/5219450/rxtx-serial-connection-issue-with-blocking-read

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!