2010-02-08 19 views
10

Ich benutze eine Linux-Box mit 2.6.9-55.ELsmp, x86_64.TCP-Empfangsfenster in C einstellen und mit tcpdump unter Linux arbeiten

Ich versuche, die TCP-Empfangsfenster zu setzen, indem die Funktion setsockopt() unter Verwendung von mit C. Ich versuche folgendes:

rwnd = 1024; 
setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&rwnd, sizeof(rwnd)); 

Das Codesegment oben in einem Client-Programm, das Daten von einem Server empfängt . Wenn ich das Programm beginnen zu empfangen und tcpdump Ausgang beobachtet, beobachte ich Fenster Verhandlungen wie folgt:

11:34:40.257755 IP clientReceiver.42464 > serverSender.8991: 
S 1742042788:1742042788(0) win 5840 
<mss 1460,sackOK,timestamp 1688222886 0,nop,wscale 2> 

Wir sehen, dass das Client-Programm ist in der Tat ein Fenster anders verhandelt, was ich in dem Client-Programm eingestellt habe. Wie ich jedoch Steven's Text ("TCP/IP Illustrated, Volume 1"), Abschnitt 20.4 interpretieren kann, glaube ich, dass Sie das, worauf er sich bezieht, im zweiten Zitat in Abschnitt 20.4 mit dem von mir verwendeten Aufruf setsockopt() bearbei- ten können (siehe oben)).

Ich würde gerne verstehen, wo ich falsch gelaufen bin.

Vielleicht ist meine Interpretation dessen, was Stevens sagt, falsch. Könnten Sie mir in diesem Fall auf die korrekte Einstellung der Empfangspuffergröße hinweisen? Als Beweis meiner Verwirrung verweise ich auf die Linux TCP-Sockets-Manpage unter http://linux.die.net/man/7/tcp (siehe Kommentar zu SO_RCFBUF).

Was vermisse ich in dieser Geschichte? Wie kontrolliere ich die Empfangspuffergröße (und zeige sie in der tcpdump-Ausgabe an)? Bitte beachten Sie, dass ich hier auf eine Einstellung der Socket-Option SO_RCFBUF anspiele - ich verstehe, dass das in der Fensteraushandlung im SYN auftaucht.

Jede Eingabe wird geschätzt.

Antwort

8

Sie müssen auch TCP_WINDOW_CLAMP die rcvbuf zweimal die Klemme

rcvbuf = 2048; 
setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)& rcvbuf, sizeof(rcvbuf)); 
clamp = 1024; 
setsockopt(sock, SOL_SOCKET, TCP_WINDOW_CLAMP, (char *)& clamp, sizeof(clamp)); 

Hinweis verwenden ist, könnte es mehr sein. Sie können es Autotune lassen, die Fensterklemme funktioniert immer noch. Dies ist nicht tragbar.

+1

Beachten Sie auch, dass die minimale Klammer auf die Hälfte des minimalen RCVBUF beschränkt ist (normalerweise 4096 - also ist die minimale Klammer normalerweise 2048). – caf

+0

Ich habe das überprüft, und die Zahlen sind eigentlich 256 und (damit) 128 für den minimal einstellbaren CLAMP-Wert resp. Überprüfen Sie den Code von tcp.c :: setsockopt() unter Groß-/Kleinschreibung TCP_WINDOW_CLAMP, und überprüfen Sie Sock.h :: # define SOCK_MIN_RCVBUF 256.Danke an alle. Prost! – Sonny

4

Die Empfangspuffergröße kann nur reduziert werden, bevor Sie den Socket anschließen - Sie können ihn jederzeit erhöhen. In welcher Reihenfolge rufen Sie sockopt() relativ zu connect() auf?

+0

Danke für die schnelle Antwort. Ich rufe setsockopt() auf, bevor ich connect(). – Sonny

-6

Bei TCP muss der Wert rwnd während des Recv übergeben werden.

recv (socke, buf, rwnd, 0);

Dies soll 1024 Bytes erhalten.

+0

Hallo, danke für deine Antwort. Von dem, was ich weiß, ist dieser recv() Anruf für die Anwendung - d.h., das ist die Rate, mit der die Anwendung den Byte-Stream verbraucht, der dafür bestimmt ist. Mit anderen Worten, ich glaube nicht, dass dies das Empfangsfenster ist, das von TCP am Anfang mit dem Peer ausgehandelt wird. – Sonny

+0

Das ist eine Anwendungspuffergröße, nicht das Empfangsfenster. Das Empfangsfenster wird durch die Socket-Empfangspuffergröße bestimmt, abzüglich wie viele anstehende Daten darin enthalten sind. – EJP