2009-09-08 16 views
6

Podczas próby ustalenia this problem (każda pomoc jest doceniana), uruchomiłem RXTX podczas monitorowania jego aktywności przy użyciu PortMon i zauważyłem, że RXTX stale sprawdza, czy dane są dostępne, nawet jeśli klient Java czyta z obiektu gnu.io.SerialPort tylko przez SerialPortEventListener.Czy konieczne jest stałe pobieranie w RXTX?

Dlaczego tak jest? Czy jest to kiepski wybór implementacji przez użytkowników RXTX, zły wybór interfejsu API przez firmę Sun (ponieważ RXTX jest zgodny z interfejsem javax.comm API), czy ograniczenie obsługi języka Java obsługiwanego przez natywny kod?

Hyperterminal, z drugiej strony, nie odpytuje (i działa bez problemu). Czy ma dostęp do niektórych ukrytych wywołań systemu Windows, które pozwalają to zrobić?

+1

Konstrukcja RXTX pozostawia wiele do życzenia. Możesz rzucić okiem na moją alternatywną bibliotekę: http://code.google.com/p/jperipheral/ – Gili

Odpowiedz

4

Nie wynika to z interfejsu API javax.xomm. Rxtx może być użyty przez to API lub nie przy okazji.

Wewnętrzne elementy Rxtx są nieco inne/dziwne i zawierają pewne błędy. Krótka wersja, tak powinna działać: Masz dwa parametry do grania: timeout i próg. Zgodnie z ustawieniem kodu źródłowego limit czasu do 0 (brak) i próg do 1 (wymagający co najmniej 1 bajta przed powrotem) powinien dać nam normalny, zdefiniowany przez InputStream, blokowanie odczytów.

Problem polega na tym, że nawet podczas konfigurowania tego jest błąd w bieżącym stabilnym wydaniu (2.1.7r2). Parametr progu jest zawsze ustawiony na 0! Z kodu źródłowego:

/* TESTOWANIE ttyset.c_cc [VMIN] = próg; */ ttyset.c_cc [VMIN] = 0;

Częściowo mylące jest to, że miało to miejsce również w 2004 r. I zostało zgłoszone na liście mailingowej i naprawione, ale nie zostało naprawione lub wróciło (regresja). W rzeczywistości istnieje nowy raport o błędzie, którego z jakiegoś powodu nie mogłem znaleźć na początku. Ostatecznie stwierdziłem, że będzie on wrzucał kod źródłowy pakietu przedpremierowego i znalazł inaczej opublikowany dziennik zmian (strona internetowa nie pokazuje dzienników zmian po ostatniej stabilnej wersji, ale jest dostępna w CVS).

Rozwiązanie

  1. Mocuje się je na głowie, dzięki czemu można korzystać z najnowszej wersji wstępnej (2,2-series) lub skompilować je z CVS.
  2. Złóż brzydki obejście wzdłuż linii:

    int read(InputStream in) throws IOException { 
        int b; 
        while ((b=in.read()) == -1) { 
        try { Thread.sleep(10); } catch (InterruptedException e) { } 
        } 
        return b; 
    } 
    

Następnie zrobić: read(in) zamiast in.read().

Właściwie napisałem a blog entry about this 2 lata temu, więc nie zapomnę.

Powiązane problemy