RXTX serial connection-problème de blocage lire()

j'essaie d'utiliser la bibliothèque RXTX pour bloquer la communication série sur Windows (XP et 7). J'ai testé la connexion avec Hyperterminal aux deux extrémités, et ça fonctionne parfaitement.

j'ai mis en place la connexion avec le code suivant: (Traitement d'exception et contrôles défensifs omis pour plus de clarté)

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

quand j'utilise

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

le message est reçu amende à l'autre extrémité, mais l'appel

inReader.readLine()

imidiately returns " java.io.IOException: le flux D'entrée sous-jacent renvoie zéro octets".

j'ai alors décidé d'essayer de mettre en œuvre mon propre blocage lire la logique et a écrit ceci:

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

mais ce code va dans une boucle infinie et" nextByte[0] = (byte)inStream.read();" attribue -1 peu importe ce qui est envoyé sur la connexion série. En outre, à l'autre extrémité bégaie assez mal et ne laisse m'envoyer un caractère toutes les 1 à 3 secondes. et pend longtemps si j'essaie d'envoyer beaucoup de personnages dans un court éclat.

Toute aide très appréciée.

*modifiez - les à l'aide de cours d'eau.lisez (nextByte)au lieu de "nextByte[0] = (byte) inStream.read (); " n'écrit pas à la variable nextByte, peu importe ce que je lui envoie à travers la connexion série.

*edit2 - que mon code fonctionne parfaitement avec le SOLEIL javax.comm lib et un win32com.dll que j'ai obtenu à partir d'un ami, j'ai cessé d'essayer de le faire fonctionner avec RXTX. Je ne suis pas intéressé à débloquer la communication, qui semble être la seule façon pour les autres personnes de faire fonctionner RXTX.

2
demandé sur dsolimano 2011-03-07 15:00:45

4 réponses

utilisez RXTX-2.2pre2, les versions précédentes ont eu un bug qui a empêché le blocage des e/s de fonctionner correctement.

et n'oubliez pas de mettre le port en mode blocage:

serialPort.disableReceiveTimeout();
serialPort.enableReceiveThreshold(1);
12
répondu DYA 2011-05-09 09:32:46

je pense que le code que vous avez écrit dans votre propre implémentation de readLine est bogué. nextByte[0] n'est jamais restauré à -1 après la lecture du premier caractère. Vous devriez essayer d'utiliser la valeur retournée par inStream.lire(nextByte) pour indiquer le nombre d'octets lus à partir du flux au lieu de la valeur de votre tableau d'octets.

quoi qu'il en soit je pense que vous devriez opter pour une méthode basée sur les événements de lecture des entrées avec un SerialPortEventListener:

serialPort.addEventListener(new SerialPortEventListener() {

      public void serialEvent(SerialPortEvent evt) {
           switch (evt.getEventType()) {
           case SerialPortEvent.DATA_AVAILABLE:
               dataReceived();
               break;
           default:
               break;
           }
      }
});
serialPort.notifyOnDataAvailable(true);
2
répondu greydet 2011-03-07 13:04:12

il ne bloque peut-être pas, mais quand le ruisseau est vide, il suffit d'attraper l'IOE et de continuer à le lire. C'est ce que je fais avec RXTX-2.1-7 et ça marche très bien, je l'utilise pour lire et écrire à un 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;
                }
            }
        }
    }
}
1
répondu arnaud 2011-08-24 14:16:37

j'ai résolu de cette façon

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

        } catch (Exception e) 
0
répondu xwalter 2014-11-12 21:35:18