2010-02-08 4 views
10

Je cours sous Linux avec une boîte 2.6.9-55.ELsmp, x86_64.Définition de la fenêtre de réception TCP en C et de l'utilisation de tcpdump sous Linux

Je suis en train de régler la fenêtre de réception TCP en utilisant la fonction setsockopt() en utilisant C. Je procédez comme suit:

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

Le segment de code ci-dessus est un programme client qui reçoit des données d'un serveur . Quand je lancer le programme pour recevoir et observer la sortie de tcpdump, je vois la négociation de la fenêtre comme ceci:

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

Nous voyons que le programme client est en fait la négociation d'une fenêtre différente de ce que j'ai mis dans le programme client. Cependant, d'après la façon dont je peux interpréter le texte de Steven ("TCP/IP Illustrated, Volume 1") Section 20.4, je crois que vous effectuez ce qu'il appelle dans la citation du second bloc de la section 20.4 en utilisant l'appel setsockopt() que j'utilise). Je voudrais comprendre où je me suis trompé. Peut-être que mon interprétation de ce que Stevens dit est peut-être incorrecte. Dans ce cas, pourriez-vous me montrer la bonne façon de régler la taille du tampon de réception? Comme preuve de ma confusion, je me réfère à la page de manuel Linux TCP sockets au http://linux.die.net/man/7/tcp (voir le commentaire sur SO_RCFBUF).

Qu'est-ce qui me manque dans cette histoire? Comment puis-je contrôler la taille du tampon de réception (et l'afficher dans la sortie tcpdump)? S'il vous plaît noter que je fais allusion ici à un paramètre de l'option de socket SO_RCFBUF - Je comprends que ce qui apparaît dans la négociation de la fenêtre dans le SYN.

Toute contribution est appréciée.

Répondre

8

Vous devez également utiliser TCP_WINDOW_CLAMP

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)); 

Notez le rcvbuf est deux fois la pince, il pourrait être plus. Vous pouvez le laisser autotune, la pince de fenêtre fonctionnera toujours. Ce n'est pas portable.

+1

Notez également que la pince minimale est limitée à la moitié du RCVBUF minimum (généralement 4096 - donc la pince minimale est généralement 2048). – caf

+0

J'ai vérifié cela, et les chiffres sont en fait 256 et (par conséquent) 128 pour la valeur CLAMP réglable minimum resp. Vérifiez le code de tcp.c :: setsockopt() dans le cas TCP_WINDOW_CLAMP, et vérifiez sock.h :: # define SOCK_MIN_RCVBUF 256.Merci à tout le monde. À votre santé! – Sonny

4

La taille du tampon de réception peut être réduite uniquement avant de connecter le socket. Vous pouvez l'augmenter à tout moment. Quel ordre appelez-vous sockopt() par rapport à connect()?

+0

Merci pour la réponse rapide. J'appelle setsockopt() avant de me connecter(). – Sonny

-6

Pour TCP, la valeur rwnd doit être transmise pendant la recv.

recv (chaussette, buf, rwnd, 0);

Cela doit recevoir 1024 octets.

+0

Salut, merci pour votre réponse. D'après ce que je sais, cet appel recv() est pour l'application, c'est-à-dire le débit auquel l'application consomme le flux d'octets qui lui est destiné. En d'autres termes, je ne crois pas que ce soit la fenêtre de réception qui est par TCP au début avec le pair. – Sonny

+0

C'est une taille de tampon d'application, pas la fenêtre de réception. La fenêtre de réception est déterminée par la taille du tampon de réception du socket moins le nombre de données en attente – EJP

Questions connexes