Подтвердить что ты не робот

Увеличение размера окна TCP

У меня есть некоторые сомнения по поводу увеличения размера окна TCP в приложении. В моем программном приложении С++ мы отправляем пакеты данных размером около 1k с клиента на сервер с использованием блокировки TCP/IP. Недавно я столкнулся с этим понятием TCP Window Size. Поэтому я попытался увеличить значение до 64K, используя setsockopt() для SO_SNDBUF и SO_RCVBUF. После увеличения этого значения я получаю некоторые улучшения в производительности для WAN-соединения, но не в подключении к локальной сети.

В соответствии с моим пониманием в размере окна TCP,

Клиент отправит пакеты данных на сервер. Достигнув этого размера окна TCP, он будет ждать, чтобы убедиться, что ACK получен с сервера для первого пакета в размере окна. В случае подключения к глобальной сети, ACK задерживается с сервера клиенту из-за задержки в RTT около 100 мс. Поэтому в этом случае увеличение размера окна TCP компенсирует время ожидания ACK и тем самым улучшает производительность.

Я хочу понять, как производительность улучшается в моем приложении.

В моем приложении даже несмотря на то, что размер окна TCP (как отправителя, так и получателя) увеличивается с использованием setsockopt на уровне сокета, мы сохраняем тот же размер пакета 1k (то есть байты, которые мы отправляем с клиента на сервер в одиночный сокет). Также мы отключили алгоритм Nagle (встроенная опция для консолидации небольших пакетов в большой пакет, тем самым избегая частого вызова сокета).

Мои сомнения таковы:

  • Поскольку я использую блокирующий сокет, для каждого пакета передачи данных из 1k он должен блокироваться, если ACK не поступает с сервера. Как повысить производительность после улучшения размера окна TCP в WAN-соединении? Если я неправильно понял концепцию размера окна TCP, пожалуйста, исправьте меня.

  • Для отправки 64 тыс. данных, я считаю, что мне все равно нужно вызвать функцию отправки сокетов 64 раза (так как я отправляю 1 кэш для отправки через блокирующий сокет), хотя я увеличил размер окна TCP до 64 КБ. Пожалуйста, подтвердите это.

  • Каков максимальный предел размера окна TCP с масштабированием окон, включенным с помощью алгоритма RFC 1323?

Я не так хорош в своем английском. Если вы не смогли понять ни одного из вышеуказанных вопросов, пожалуйста, дайте мне знать.

4b9b3361

Ответ 1

Прежде всего, из вашего вопроса видно большое заблуждение: размер окна TCP - это то, что контролируется SO_SNDBUF и SO_RCVBUF. Это неверно.

Каков размер окна TCP?

Вкратце, размер окна TCP определяет, сколько последующих данных (пакетов) ваш сетевой стек желает поставить на провод, прежде чем получать подтверждение для самого раннего пакета, который еще не был подтвержден.

Стек TCP должен жить и учитывать тот факт, что после того, как пакет был определен как потерянный или искаженный во время передачи, каждый отправленный пакет с этого момента должен быть повторно отправлен, поскольку пакеты могут быть только подтвержденного в порядке получателя. Поэтому, позволяя слишком много неподтвержденных пакетов существовать в то же время, спекулятивно использует пропускную способность соединения: нет гарантии, что используемая полоса пропускания фактически приведет к чему-либо полезному.

С другой стороны, не позволяя нескольким неподтвержденным пакетам в одно и то же время просто уничтожить пропускную способность соединений, которые имеют высокий продукт задержки полосы пропускания. Таким образом, стек TCP должен балансировать между использованием полосы пропускания без каких-либо преимуществ и не слишком сильно управлять трубой (и, таким образом, позволяя некоторым ее возможностям не использовать).

Размер окна TCP определяет, где находится этот баланс.

Что делают SO_SNDBUF и SO_RCVBUF?

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

Если один из этих буферов заполнен, вы не сможете отправлять или получать больше данных, пока не освободится некоторое пространство. Обратите внимание, что эти буферы влияют только на то, как сетевой стек обрабатывает данные на "ближней" стороне сетевого интерфейса (до того, как они были отправлены или после их поступления), в то время как окно TCP влияет на то, как стек управляет данными на "дальнем", (т.е. на проводе).

Ответы на ваши вопросы

  • Нет. Если бы это было так, вы бы понесли задержку в оба конца для каждого отправленного пакета, что полностью разрушило бы пропускную способность соединений с высокой задержкой.

  • Да, но это не имеет никакого отношения ни к размеру окна TCP, ни к размеру буферов, выделенных этому сокету.

  • По всем источникам я смог найти (пример), масштабирование позволяет максимальному размеру окна 1 ГБ.

Ответ 2

  • Так как я использую блокирующий сокет, для каждого пакета передачи данных 1k он должен блокироваться, если ACK не приходит с сервера.

Неправильно. Отправка в TCP асинхронна. send() просто передает данные в буфер отправки сокетов и возвращает их. Он блокируется только в том случае, когда буфер отправки сокета заполнен.

Затем как повысить производительность после улучшения размера окна TCP в одном только соединении WAN?

Потому что вы ошибались в этом, блокируя, пока не получили ACK.

  • Для отправки 64K данных я считаю, что мне еще нужно вызвать функцию отправки сокетов 64 раза

Почему? Вы можете просто вызвать его один раз с буфером данных 64k.

(так как я отправляю 1k для отправки через блокирующий сокет)

Почему? Или это повторение вашего заблуждения в соответствии с (1)?

хотя я увеличил размер окна TCP до 64K. Пожалуйста, подтвердите это.

Нет. Вы можете отправить все сразу. Никакой цикл не требуется.

Каков максимальный предел размера окна TCP с масштабированием окон, включенным с помощью алгоритма RFC 1323?

Значительно больше, чем вам когда-либо понадобится.