Настройка TCP-приемника на C и работа с tcpdump в Linux
Я запускаю Linux-сервер под управлением 2.6.9-55.ELsmp, x86_64.
Я пытаюсь установить окно приема 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.
Приветствуется любой ввод.
Ответы
Ответ 1
Вам также нужно использовать 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 в два раза больше зажима, это может быть больше. Вы можете позволить автотуне, оконный зажим все равно будет работать. Это не переносимо.
Ответ 2
Размер буфера приема может быть уменьшен только до подключения сокета - вы можете увеличить его в любое время. Какой порядок вы вызываете sockopt() по отношению к connect()?
Ответ 3
Для TCP значение rwnd должно быть передано во время recv.
recv (sock, buf, rwnd, 0);
Это будет принимать 1024 байта.