RXTX последовательное соединение - проблема с блокировкой чтения () - PullRequest
2 голосов
/ 07 марта 2011

Я пытаюсь использовать библиотеку RXTX для блокировки последовательной связи в Windows (XP и 7).Я проверил соединение с Hyperterminal на обоих концах, и оно работает безупречно.

Я установил соединение с помощью следующего кода: (обработка исключений и защитные проверки опущены для ясности)

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()));

Когда я использую

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 секунды.и зависает в течение долгого времени, если я пытаюсь отправить много символов в короткий пакет.

Любая помощь очень ценится.

* edit - использование inStream.read (nextByte) вместо "nextByte [0] = (байт) inStream.read (); "не записывает в переменную nextByte, независимо от того, что я посылаю ей через последовательное соединение.

* edit2 - так как мой код работает безупречно с библиотекой SUN javax.comm и win32com.dll, которые я получил отдруг, я перестал пытаться заставить его работать с RXTX.Меня не интересует разблокировка связи, которая, кажется, является единственным способом, которым другие люди могут заставить работать RXTX.

Ответы [ 4 ]

12 голосов
/ 09 мая 2011

Использовать RXTX-2.2pre2, в предыдущих версиях была ошибка, из-за которой блокировка ввода / вывода работала некорректно.

И не забудьте установить порт в режим блокировки:

serialPort.disableReceiveTimeout();
serialPort.enableReceiveThreshold(1);
2 голосов
/ 07 марта 2011

Я думаю, что код, который вы написали в своей собственной реализации 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);
1 голос
/ 24 августа 2011

это не может быть блокировка, но когда поток пуст, просто перехватите 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;
                }
            }
        }
    }
}
0 голосов
/ 13 ноября 2014

Я решил таким образом

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

        } catch (Exception e) 
...