Warum ist es davon ausgegangen, dass senden können zurück, mit weniger als die angeforderten Daten übertragen, die auf einem blockierenden socket?

Die standard-Methode zum senden von Daten über einen stream-socket seit jeher zu rufen, senden, mit einem Stück von Daten zu schreiben, überprüfen Sie den Rückgabewert, um festzustellen, ob alle Daten gesendet wurden und dann halten Sie den Aufruf erneut senden, bis die gesamte Nachricht akzeptiert wurde.

Zum Beispiel dies ist ein einfaches Beispiel für eine gemeinsame Regelung:

int send_all(int sock, unsigned char *buffer, int len) { 
int nsent; 

while(len > 0) { 
nsent = send(sock, buffer, len, 0); 
wenn(nsent == -1) //Fehler 
return -1; 

Puffer += nsent; 
len -= nsent; 
} 
return 0; //ok, alle Daten, die gesendet werden 
} 

Sogar die BSD-manpage erwähnt, dass

...Wenn keine Nachrichten Speicherplatz verfügbar ist auf dem sockel zu halten, wird die Nachricht übertragen werden soll, dann senden() normalerweise Blöcke...

Was bedeutet, dass wir davon ausgehen sollten, dass senden können zurück, ohne das senden aller Daten. Jetzt finde ich diese eher gebrochen, aber auch W. Richard Stevens meint dazu in seinem Standardwerk über Netzwerk-Programmierung, nicht am Anfang der Kapitel, aber die fortgeschrittenen Beispiele verwendet seine eigenen geschrieben (write all data) - Funktion anstelle des Aufrufs schreiben.

Nun halte ich diese immer noch mehr oder weniger kaputt, da, wenn der Versand nicht in der Lage ist die übertragung aller Daten, oder übernehmen Sie die Daten in der zugrunde liegenden Puffer und der socket blockiert, dann senden blockieren sollte und zurückkehren, wenn die ganze Anfrage senden akzeptiert wurde.

Ich meine, im code-Beispiel oben, was passieren wird, wenn Retouren senden Sie mit weniger Daten gesendet, ist, dass es aufgerufen wird, werden die Rechte wieder mit einem neuen Antrag. Was hat sich geändert seit dem letzten Aufruf? Bei max ein paar hundert CPU-Zyklen bestanden haben, damit der Puffer noch voll. Wenn Sie jetzt akzeptiert die Daten, warum konnte nicht Sie es akzeptieren, dass es vor?

Sonst werden wir Ende upp mit einer ineffizienten Schleife, wo wir versuchen, zum senden von Daten über ein socket kann Daten annehmen und weiter versuchen, oder anderes?

So scheint es, die Problemumgehung, wenn nötig, Ergebnisse in stark ineffizienten code und in einem solchen Fall blockieren von sockets sollte vermieden werden, überhaupt eine non-blocking sockets zusammen mit wählen sollte stattdessen verwendet werden.

InformationsquelleAutor Ernelli | 2010-04-11
Schreibe einen Kommentar