TWinSocketStream->Read - nie czyta wszystkich bajtów

0

Witam,

wygląda to tak:

  • otwieram Socket'a i strumień
try{
xsock->Open();
}
    catch (...) {
    // obsluga
}

TWinSocketStream * polaczenie = new (nothrow) TWinSocketStream(xsock->Socket, 3000);

jest ok.
Wysyłam komendę startu do urządzenia. Odpowiada dwoma bajtami: 1,1 ok, 2,2 błąd. Jedziemy dalej.
Wysyłam dane do urządzenia (ok 12 kB). I urządzenie po odbiorze ustalonej ilości danych odpowiada mi pięcioma jedynkami jeśli ok, lub 2 i CRC32 (w sumie 5[B]) jeśli błąd.

I pojawia się problem: czasem ostatni Bajt (piąty) nie przychodzi. Przychodzą np. cztery jedynki.

Kawałek kodu wygląda tak:

unsigned char odpowiedz [6] = {0, 0, 0, 0, 0, 0};
            /*if(!xpolaczenie->WaitForData(1500)){   // nic nie zmienia
                return false;
            } */
            try{xpolaczenie->TStream::ReadBuffer(odpowiedz, xiOdpIle);}
            catch(...){
                return false;
            }
            //Timeout = xpolaczenie->Read(odpowiedz, xiOdpIle);  // funkcja Read
            //if (Timeout == 0) {
            //    return false;
            //}

                if (odpowiedz[0] != 1 || odpowiedz[1] != 1 || odpowiedz[2] != 1
                                      || odpowiedz[3] != 1 || odpowiedz[4] != 1) {

                    if(odpowiedz[0] == 2){
                        // wyswietlenie CRC32
                    }else{
                        // sprawdzam sobie co dostalem i tu wlasnie widac ze czasem ostatni Bajt nie przychodzi (=0)
                        AnsiString errm = "1: " + IntToStr((int)odpowiedz[0]) + ".  2: " + IntToStr((int)odpowiedz[1]) +
                        ".  3: " + IntToStr((int)odpowiedz[2]) + ".  4: " + IntToStr((int)odpowiedz[3]) + ".  5: " + IntToStr((int)odpowiedz[4]);
                        ShowMessage(errm);                        
                    }
                    return false;
                }else{
                    // jest ok
                }
            

Jak widać w kodzie: najpierw wysyłałem funkcją - Read, później ReadBuffer i to samo. ReadBuffer gdy nie dostanie 5 bajtów to sobie rzuca wyjątkiem.

Urządzenie wysyła 5 bajtów na 100% - badane na programie Terminal.

Parametry połączenia: 230400 bps, 8N1 przez transceiver LAN -> UART.

Jakieś pomysły?

0

ReadBuffer gdy nie dostanie 5 bajtów to sobie rzuca wyjątkiem

jesli tak jest, to do miejsca oznaczonego:

// sprawdzam sobie co dostalem i tu wlasnie widac ze czasem ostatni Bajt nie przychodzi (=0)

program nie dojdzie, wiec jak moze w tym miejscu byc to widac?

druga sprawa, "ostatni Bajt nie przychodzi (=0)". skoro ostatni bajt o ostatni bajt CRC32, to przeciez ma prawo byc naturalnym zerem? przypadek czterech jedynek.. dziwne. sprawdzales czy ramki wysylane przez urzadzenie sa poprawne? moze cos sie przesuwa, albo jest blednie interpretowane jako kawalek naglowka? czy w ogole jest bezramkowo i 'gole' dane lataja?

0

ReadBuffer gdy nie dostanie 5 bajtów to sobie rzuca wyjątkiem

jesli tak jest, to do miejsca oznaczonego:
// sprawdzam sobie co dostalem i tu wlasnie widac ze czasem ostatni Bajt nie przychodzi (=0)

program nie dojdzie, wiec jak moze w tym miejscu byc to widac?

Przychodzi do tego miejsca. ReadBuffer rzuca jak nie dostanie tylu bajtów ile miał odebrać. Poza tym najpierw testowałem na Read.

druga sprawa, "ostatni Bajt nie przychodzi (=0)". skoro ostatni bajt o ostatni bajt CRC32, to przeciez ma prawo byc naturalnym zerem?

CRC32 przychodzi tylko jak jest błąd. Gdy pierwszy bajt równa się 2 to pozostałe cztery są CRC32. A gdy pierwszy = 1 to pozostałe cztery też muszą być = 1.

sprawdzales czy ramki wysylane przez urzadzenie sa poprawne

Tak jak napisałem w poście - badane programem Terminal. Taki sniffer na UARTy. Urządzenie wysyła 5 bajtów na 100%.

Po zmianie protokołu - ustaleniu długości odpowiedzi na 6 bajtów, zdarza się, że 5 i 6 bajt nie przychodzą, albo sam szósty nie przychodzi. Ktoś podrzucił pomysł, żeby spróbować na czystych WinAPI socketach spróbować - czyli send, recv.. Ale wątpię, by kontrolki były tak skopane.

0

Hmm.. Terminal zainstalowany był na komputerze gdzie urządzenie było bezpośrednio programowane. I słuchał na COMie.

Ja komunikuję się z nim po sieci i zainstalowałem sobie jakiegoś sniffera i pokazuje mi, że przyszło 5 bajtów, a u mnie w programie pokazuje, że 4. Więc faktycznie chyba ta kontrolka jest masakryczna?! Ale to przecież podstawowa funkcja. Nie może odczytać poprawnie 5 bajtów?? Najgorsze, że u siebie w programie nie widzę, żadnego błędu - trudno go tu w ogóle zrobić.

1 użytkowników online, w tym zalogowanych: 0, gości: 1