Kann ‘Send’ bei C-TCP-Sockets Null zurückgeben?

Lesezeit: 4 Minuten

Ist es jemals möglich, dass C send Funktion, um Null zurückzugeben, wenn TCP-Sockets verwendet werden? Die Manpage sagt nur, dass es die Anzahl der gesendeten Bytes zurückgibt, aber ich bin mir nicht sicher, ob es nur -1 zurückgibt, wenn es keine Daten senden kann.

Benutzer-Avatar
paxdiablo

Ich bin mir ziemlich sicher, obwohl der Speicher tief im Nebel der Zeit liegt, dass ich schon einmal gesehen habe, dass er in Situationen massiver Datenübertragungen, bei denen das andere Ende nicht mitgehalten hat, Null zurückgegeben hat.

Aus dem Speicher waren in diesem Fall die Remote-TCP-Stack-Puffer gefüllt, der Stack hatte dem lokalen Ende mitgeteilt, dass er warten sollte, bis etwas Platz frei wurde und die lokalen Puffer ebenfalls gefüllt waren.

An diesem Punkt ist es technisch gesehen kein Fehler (daher wird keine -1 zurückgegeben), aber der lokale Stack konnte keine Daten akzeptieren.

Ich bin nicht völlig Sicher ist, dass dies jetzt der Fall ist, da der aktuelle Posix-Standard darauf hinzudeuten scheint, dass er in diesem Fall einfach blockiert (oder fehlschlägt, wenn er für Nicht-Blockierung eingerichtet ist).

Ich vermute jedoch, dass es sich um einen strittigen Punkt handelt. Du tun die Möglichkeit haben, dass es zurückkehrt weniger als die Bytes, die Sie senden wollten, und Sie sollten daher Code haben, um damit umzugehen.

Und da es so ziemlich die gleiche Logik ist, die “eins weniger als das, was Sie angefordert haben”, behandelt wie “null Bytes”, können Sie genauso gut davon ausgehen, dass es Null zurückgeben kann.

  • Wie soll ich damit umgehen? Soll mein Programm weiterhin versuchen zu senden oder sollte es fehlschlagen?

    – Adrian

    21. Juni 2010 um 4:25 Uhr

  • Sie sollten weiterhin versuchen zu senden, da dies kein Fehlerzustand ist. Wenn es sich nicht erholt, erhalten Sie schließlich einen Fehler zurück. Das ist der Punkt, an dem Sie einen Fehler anzeigen sollten. Eines du kann Was Sie in Betracht ziehen möchten, ist die Einführung einer Verzögerung nach einem Rückgabecode von Null, bevor Sie es erneut versuchen. Das würde mehr Zeit für ein vorübergehendes Problem geben, um sich selbst zu beheben. Es gibt eine Reihe von Strategien, die Sie dafür verfolgen können.

    – paxdiablo

    21. Juni 2010 um 4:31 Uhr


  • wäre dies nicht nur in einem nicht blockierenden Szenario?

    – jdizzle

    21. Juni 2010 um 4:40 Uhr

  • @paxdiablo: Ich glaube nicht, dass deine Erklärung richtig ist. Wenn sich der Socket im Blockiermodus befindet und der Empfänger meldet, dass sein Empfangspuffer voll ist, blockiert send() einfach, bis er wieder Daten senden kann (oder ein schwerwiegender Fehler/Zeitüberschreitung auftritt). Wenn sich der Socket stattdessen im nicht blockierenden Modus befindet, kehrt er sofort mit -1 und einem Fehlercode von EWOULDBLOCK zurück. Meiner Erfahrung nach bedeutet ein Rückgabewert von 0 immer, dass entweder 0 Bytes an send() übergeben wurden, oder die andere Partei den Socket ordnungsgemäß geschlossen hat (oder zumindest shutdown(0) aufgerufen hat).

    – Rémy Lebeau

    23. Juni 2010 um 22:36 Uhr

  • @RemyLebeau Ich stimme zu. Das Verhalten von send() ist nicht implementierungsabhängig, im Gegensatz zu dem, was in dieser Antwort behauptet wird. Es wurde vor Jahrzehnten von BSD und dann von Posix definiert. Ihr Kommentar zu “Die andere Partei hat ordnungsgemäß geschlossen” ist jedoch nicht korrekt. Das führt zu ECONNRESET, wenn Sie weiter senden, nicht zu einem Rückkehrcode von Null.

    – Benutzer207421

    24. Februar 2014 um 7:39 Uhr


Nun, es gibt immer den Fall, in dem Sie Null als Anzahl der zu sendenden Bytes übergeben haben … in diesem Fall würde “Rückgabe der Anzahl der gesendeten Bytes” anzeigen, dass Null Bytes zurückgegeben werden sollten.

Wahrscheinlich ist es sowieso am besten, den Rückgabe-Null-Fall richtig zu handhaben; es kann nicht schaden, und es könnte helfen.

Die Antwort darauf kann durchaus implementierungsabhängig sein und daher je nach Betriebssystem variieren.

Ein Umstand, wo 0 erwartet würde, wenn Sie eine Übertragung von 0 Bytes anfordern.

  • eigentlich ist es nicht implementierungsabhängig. Es ist sehr wahrscheinlich, dass Sie darum gebeten haben, etwas zu senden, während das Empfangsfenster des empfangenden TCP voll ist oder während der Sendepuffer des sendenden TCP vollständig voll ist. In solchen Fällen könnte send() leicht Null zurückgeben.

    – Chris Cleeland

    3. April 2011 um 20:24 Uhr

  • In diesen Fällen würde send() entweder blockieren, bis Platz verfügbar ist (und dann einen Wert größer als Null zurückgeben), oder wenn sich der Socket im nicht blockierenden Modus befindet, würde er -1/EWOULDBLOCK zurückgeben

    – Jeremy Friesner

    17. Oktober 2018 um 16:54 Uhr


Der BSD Mann Seite gibt an:

Wenn am Socket kein Platz für Nachrichten verfügbar ist, um die zu übertragende Nachricht aufzunehmen, blockiert send() normalerweise, es sei denn, der Socket wurde in den nicht blockierenden E/A-Modus versetzt.

Die Posix-Spezifikation geht noch weiter und besagt, dass im Blocking-Modus alle Daten werden übertragen, es sei denn, es tritt ein Interrupt auf.

In beiden Fällen kann Null nicht zurückgegeben werden, es sei denn, die gelieferte Zählung war Null.

Benutzer-Avatar
jno

Ich beobachte eine Nullrückkehr von der send(2) auf ein AF_UNIX Geben Sie jetzt Socket ein.

Jepp, es lag an der size Feld mit Nullwert.

Also, JFYI.

1166950cookie-checkKann ‘Send’ bei C-TCP-Sockets Null zurückgeben?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy