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 W2K

    Danke 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 formuliere

    while (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? 😕


Anmelden zum Antworten