TCP recv. Letztes Byte kommt _manchmal_ nicht an
-
Hallo Leute,
habe folgendes Problem. Ich benötige eine TCP-Verbindung und möchte darüber Binärdaten austauschen. Damit ich weiß, wieviele Daten kommen werden, übertrage ich die Länge im Vorfeld. Jetzt passiert es aber manchmal, daß das letzte Byte nicht ankommt und ich im geblockten recv hängen bleibe. Das passiert in ca 3% der Fälle. Mir kommt auch vor, daß dieser Effekt erst ab einer gewissen Größe auftritt. (ca 8620 bytes)
Kennt ihr das Problem, bzw auch eine Lösungsmöglichkeit?
VC++ unter W2KDanke euch,
Joe
-
Du wirst doch nicht versuchen das ganze mit nur einem recv() zu empfangen, oder?
-
Nein, das nicht
Zuerst übertrage ich die Länge, dann kommt diese Schleife:do { received_bytes = recv(sock_,buffer,8000,0); total_received_bytes += received_bytes; // *data += std::string(buffer,received_bytes); remaining_bytes -= received_bytes; printf("%i bytes remaining - %i bytes received\n", remaining_bytes,received_bytes); } while (remaining_bytes >0);
Und hier fehlt manchmal ein Byte, also bleibt remaining_bytes auf 1
Joe
-
received_bytes = recv(sock_,buffer,8000,0); if(received_bytes==-1){ if(last_error==kommtGleichOderWieDasHeisst){ //puh, nix passiert. gleich kommts. } else{ cerr<<"mist, was schlimmes"<endl; die(); } } total_received_bytes += received_bytes;
ups. if(last_error==kommtGleichOderWieDasHeisst){
kann ja gar nicht vorkommen, wenn du blocking sockets hast.aber was anderes. bei microsoft isses afair so, daß du nen fehler "connectionClosesSuccessfully" kriegst, wenn der andere shutdown gemacht hat. also eine -1 kommt, statt einer 0 beim letzten paket. irgendsowas komisches war da.
-
Hallo volkard.
Also fehler kommt ja keiner. Es sind nur zu wenige Daten angekommen. Das letzte Byte kommt nie an. (wenn ich die abfrage unsauber formulierewhile (remaining_bytes >1);
gehts ja. Dann steig ich manchmal mit remaining_bytes == 1 aus.
Das ist der Output, den ich zu 97 % erhalte (alles läuft glatt)
waiting for data - 8609 bytes remaining 4886 bytes remaining - 3723 bytes received 1422 bytes remaining - 3464 bytes received 0 bytes remaining - 1422 bytes received remaining bytes=0
Und hier bleib ich stecken, wenn ich ein paar mal das Programm starte
waiting for data - 8609 bytes remaining 4886 bytes remaining - 3723 bytes received 4302 bytes remaining - 584 bytes received 566 bytes remaining - 3736 bytes received 1 bytes remaining - 565 bytes received
Demnach war die letzte Meldung von recv, daß 565 bytes empfangen wurden und 1 byte fehlt noch. -> erneut warten, bis das eine Byte da ist.
Ich stell den source mal online
http://www.sbox.tugraz.at/home/r/reiterj/tcp.zip
Ein paar mal muß man starten, damit das Problem sichtbar wird.Gruß, Joe
-
Warum hast du bei send MSG_OOB angegeben?
-
Ohne tritt das Problem nämlich nicht ein. Mit MSG_OOB tritt es bei mir immer ein.
-
MSG_OOB schrieb:
Warum hast du bei send MSG_OOB angegeben?
Stupides Verwenden eines Samples aus der MSDN
Danke dir, derweilen tritt das Problem nicht auf. Ich werde einfach mal drauf los testen.
Besten Dank an alle!
Gruß,
Joe
-
joerider schrieb:
Hallo volkard.
Also fehler kommt ja keiner. Es sind nur zu wenige Daten angekommen. Das letzte Byte kommt nie an.ich meine auch keine echten fehler, sondenr pseudofehler. wenn recv zwar -1 liefert, aber das kein fehler ist, sondern nur ne bescheidsagung. und die -1 addierst du zu den gelesenen bytes! damit denkste dann, wein byte zu wenig gelesenb zu haben, obwohl alles ok ist.
-
volkard schrieb:
joerider schrieb:
Hallo volkard.
Also fehler kommt ja keiner. Es sind nur zu wenige Daten angekommen. Das letzte Byte kommt nie an.ich meine auch keine echten fehler, sondenr pseudofehler. wenn recv zwar -1 liefert, aber das kein fehler ist, sondern nur ne bescheidsagung. und die -1 addierst du zu den gelesenen bytes! damit denkste dann, wein byte zu wenig gelesenb zu haben, obwohl alles ok ist.
Wenn das hier der Fall gewesen wäre, müsste remaining_bytes im Schleifendurchlauf davor doch aber 0 gewesen sein um auf 1 zu kommen und die Schleife wäre abgebrochen worden, oder nicht?