2011-07-13 10 views
9

Na podstawie opinii @ Len-Holgate in this question, asynchronicznie żądam odczytywania 0-bajtowego, a w oddzwanianiu akceptuję bajty dostępnych bajtów z odczytami synchronicznymi, ponieważ wiem, że dane są dostępne i nie będą blokowane. Wydaje się to tak skuteczne i cudowne.SslStream odpowiednik TcpClient.Available?

Ale potem dodaję opcję dla SslStream, a podejście rozpada się. Odczyt zera bajtów jest w porządku, ale SslStream odszyfrowuje bajty, pozostawiając zerową liczbę bajtów w buforze TcpClient (odpowiednio) i nie mogę określić, ile bajtów znajduje się teraz w SslStreamie do odczytu.

Czy jest to prosta sztuczka?


Niektóre kodu, tylko dla kontekstu:

sslStream.BeginRead(this.zeroByteBuffer, 0, 0, DataAvailable, this); 

A po EndRead() (które poprawnie zwraca 0) DataAvailable zawiera:

// by now this is 0, because sslStream has already consumed the bytes 
available = myTcpClient.Available; 

if (0 < available) // Never occurs 
{ 
    // this part can be distractingly complicated, but 
    // it's based on the available byte count 
    sslStream.Read(...); 
} 

i ze względu na protokół , Muszę ocenić bajt po bajcie i dekodować bajt o zmiennej szerokości bajtów i inne. Nie chcę czytać bajt po bajcie asynchronicznie!

+3

Zbudowałem wiele aplikacji opartych na gniazdach, z lub bez SSL, synchroniczne lub asynchroniczne. Ale nigdy nie spotkałem się z sytuacją, w której potrzebowałbym znać liczbę dostępnych bajtów. Posunąłbym się tak daleko i zadzwoniłbym do aplikacji, która na nim polegała. Czy możesz wyjaśnić, dlaczego twój kod tego potrzebuje? Dlaczego po prostu nie poprosisz byteBuffer.Length wiele bajtów? – dtb

+1

Ponieważ nie wiem, ile bajtów będę musiał otrzymać wcześniej, w tym przypadku, znak nowej linii. Jeśli poproszę o 1024 bajty, to wywołanie zwrotne nie powróci, dopóki nie będzie dostępnych 1024 bajtów (lub koniec strumienia zostanie osiągnięty z powodu zamknięcia gniazda). O ile się nie mylę? –

+2

Zarówno Odczyt, jak i Początek zwracają tylko to, co jest dostępne, chyba że nic nie jest dostępne, w takim przypadku czekają, aż co najmniej jeden bajt stanie się dostępny lub strumień zostanie zamknięty. Na przykład, jeśli zażądasz 1024 bajtów, zwrócą one od 1 do 1024 bajtów, ale nie będą czekać, aż otrzymają dokładnie 1024 bajty. – dtb

Odpowiedz

1

Jeśli dobrze zrozumiałem, twoje wiadomości są rozdzielane przez pewną postać i już używasz StringBuilder, aby zakryć sprawę, gdy wiadomość jest podzielona na kilka części.

Można rozważyć ignorowanie ogranicznika podczas odczytywania danych, dodawania do nich wszelkich danych, gdy staną się one dostępne, a następnie sprawdzanie lokalnego znaku StringBuilder dla znaku ogranicznika. Po znalezieniu można wyodrębnić pojedynczą wiadomość za pomocą sb.ToString(0, delimiterIndex) i , dopóki nie pozostaną żadne ograniczniki.

Obejmuje to również przypadek, w którym dwa komunikaty są odbierane jednocześnie.