2010-02-08 3 views
10

Я запускаю Linux-сервер под управлением 2.6.9-55.ELsmp, x86_64.Настройка окна приема TCP в C и работа с tcpdump в Linux

Я пытаюсь установить TCP окна приема с помощью функции setsockopt() с использованием C. Я пытаюсь следующее:

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

Сегмент кода выше находится в клиентской программе, которая получает данные от сервера , Когда я пнуть программу для приема и наблюдать выход TCPDUMP, я наблюдаю окно переговоров, как так:

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

Мы видим, что клиентская программа фактически переговорное окно, отличное от того, что я поставил в клиентской программе. Однако из того, как я могу интерпретировать текст Стивена («TCP/IP Illustrated, Volume 1»), раздел 20.4, я считаю, что вы используете то, что он ссылается во второй цитате блока в разделе 20.4, используя вызов setsockopt(), который я использую (см. Выше).

Я хотел бы понять, где я поступил неправильно.

Возможно, моя интерпретация того, что говорит Стивенс, неверна. В этом случае вы могли бы указать мне правильный способ установки размера буфера приема? В качестве доказательства моей путаницы я ссылаюсь на справочную страницу сокетов Linux TCP по адресу http://linux.die.net/man/7/tcp (см. Комментарий к SO_RCFBUF).

Что мне не хватает в этой истории? Как управлять размером буфера приема (и показывать его на выходе tcpdump)? Обратите внимание, что я ссылаюсь на здесь параметр сокета SO_RCFBUF - я понимаю, что это видно в согласовании окна в SYN.

Любой ввод оценивается.

ответ

8

Вы должны также использовать 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)); 

Обратите внимание на rcvbuf вдвое зажим, он может быть больше. Вы можете позволить автотуне, оконный зажим все равно будет работать. Это не переносимо.

+1

Обратите также внимание, что минимальный зажим ограничен половиной минимального RCVBUF (обычно 4096 - поэтому минимальный зажим обычно равен 2048). – caf

+0

Я проверил это, и цифры на самом деле являются 256 и (таким образом) 128 для минимально устанавливаемого значения CLAMP или. Проверьте код из tcp.c :: setsockopt() в случае TCP_WINDOW_CLAMP и проверьте sock.h :: # define SOCK_MIN_RCVBUF 256.Спасибо всем. Ура! – Sonny

4

Размер буфера приема может быть уменьшен только до подключения сокета - вы можете увеличить его в любое время. Какой порядок вы вызываете sockopt() по отношению к connect()?

+0

Спасибо за быстрый ответ. Я вызываю setsockopt() перед тем, как подключиться(). – Sonny

-6

Для TCP значение rwnd должно быть передано во время recv.

recv (носок, buf, rwnd, 0);

Это будет принимать 1024 байта.

+0

Привет, спасибо за ваш ответ. Из того, что я знаю, этот вызов recv() для приложения - то есть, это скорость, с которой приложение потребляет поток байтов, предназначенный для него. Другими словами, я не считаю, что это окно получения, которое является , оговорено по TCP в начале с одноранговым узлом. – Sonny

+0

Это размер буфера приложения, а не окно приема. Окно приема определяется размером буфера приема сокета, меньше количества ожидающих данных. – EJP