2012-11-26 11 views
5

Ich habe einige Probleme die Arbeits von Sockets in Linux zu verstehen.Wie ist es möglich, Send-Timeout auf einem nicht blockierenden Socket zu haben?

setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(int)); 
write = write(sockfd, buf, len); 

In dem obigen Code als Schreibvorgänge gepuffert werden, Timeout senden macht keinen Sinn (Schreibsystemaufruf sofort zurückkehren wird, wenn die User-Space-Puffer in den Kernel-Puffer kopiert wird). Sende-Puffer-Größe ist viel wichtiger Parameter, aber Sende-Timeout scheint es tut nichts wert. Aber ich bin sicher falsch, da ich ziemlich viel Code gesehen habe, der SO_SNDTIMEO verwendet. Wie kann der Zeitcode für die Benutzerraumcodierung mithilfe von SO_SNDTIMEO unter der Annahme, dass der Empfänger sehr langsam ist, überschritten werden?

+0

Können Sie klären, was Ergebnis, das Sie erreichen wollen? –

+2

Es gibt kein Ergebnis, das ich zu erreichen versuche, ich habe diese Frage gestellt, um die Funktionsweise von Sockets zu verstehen und warum gibt es SO_SNDTIMEO überhaupt? – 0xhacker

+0

Diese Antwort könnte helfen zu verstehen, SO_SNDTIMEO: http://stackoverflow.com/a/4182564/10682 –

Antwort

6

Wie ist es möglich, Send-Timeout auf einem nicht blockierenden Sockel zu haben?

Es ist nicht. Timeouts sind für den Sperrmodus. Ein nicht blockierendes recv() blockiert nicht und kann daher auch nicht ausgelaufen werden.

Ich habe eine Menge Code gesehen, der SO_SNDTIMEO verwendet.

Nicht im nicht blockierenden Modus, es sei denn, der betreffende Code ist Unsinn.

+0

In Linux wie stellen Sie sicher, dass das Senden oder Schreiben in ein Paket blockiert wird, dh. Schreiben oder Senden von Returns nur, wenn der Kernel die ACK für die gesamte Länge des Puffers erhalten hat (der Puffer wird in mehrere TCP-Pakete aufgeteilt) – 0xhacker

+0

@ mc_87 Sie können nicht. Wenn Sie eine Bestätigung wünschen, müssen Sie diese selbst auf Anwendungsebene senden. – EJP

+0

Also, dann, wie wird SO_SNDTIMEO jemals nützlich sein, wenn auf Anwendungsebene kann ich nicht bis zu meinem letzten TCP-Ack blockieren? – 0xhacker

4

SO_SNDTIMEO ist für einen blockierenden Socket nützlich. Wenn der Puffer des Sockets voll ist, kann send() blockieren. In diesem Fall kann es nützlich sein, die Socket-Option SO_SNDTIMEO zu verwenden. Für nicht-blockierende Sockets, wenn der Puffer des Socket voll sind, sofort fehl senden, so gibt es keinen Punkt SO_SNDTIMEO mit einem nicht blockierenden Socket bei der Einrichtung.