Какова цель опции сокета SO_SNDLOWAT - PullRequest
7 голосов
/ 23 ноября 2011

В настоящее время я портирую программное обеспечение на C с Tru64 на Linux Suse 11. На Tru64 они устанавливают для параметра сокета SO_SNDLOWAT значение 1024 * 64.В Linux эта опция не изменяется, и ее значение равно 1.

Я хочу выяснить, как повлияет отсутствие установки SO_SNDLOWAT в 1024 * 64 на выполнение программного обеспечения в Linux.

Проблема в том, что я нашел два определения (интерпретации) цели SO_SNDLOWAT:

  1. На странице руководства по сокетам в Linux:

    SO_SNDLOWAT
    Укажите минимальное количество байтов в буфере до тех пор, пока уровень сокета не передаст данные в протокол

    Я понял, что он указывает минимальное количество байтов в буфере дляпродолжить (в данном случае для отправки сообщения).Буфер должен быть заполнен, по крайней мере, для SO_SNDLOWAT байтов, чтобы продолжить

  2. Обнаружено в книге " Сетевое программирование в UNIX: сетевой интерфейс сокетов У. Ричарда Стивенса, БиллФеннер, Эндрю М. Рудофф"

    Низкая отметка отправки - это количество доступного пространства, которое должно существовать в буфере отправки сокета для выбора, чтобы возвратить" доступный для записи ".

    Я понял, что если я хочу записать в буфер сокетов (независимо от размера того, что я пишу), в буфере должно быть по крайней мере SO_SNDLOWAT байт.

Я не знаю, что из SO_SNDLOWAT.

Ответы [ 3 ]

2 голосов
/ 14 июля 2017

Как вы можете видеть в этом вопросе , который охватывает другие варианты сокетов, ответ зависит от операционной системы, поэтому оба ответа могут быть правильными, так как один является ответом из мира Linux, а другой -ответ из мира UNIX (BSD и Co).

В клонах BSD и BSD эта опция означает следующее:

  1. Если сокет неблокируя и вызывая send(), он должен иметь возможность либо принять все предоставленные данные одновременно, либо принять не менее SO_SNDLOWAT байтов данных;если это невозможно, он не примет никаких данных и send() завершится с ошибкой.

    Таким образом, если вы установите SO_SNDLOWAT на 100 и попытаетесь отправить 50 байтов, он отправит 50 байтов или ничего.Если вы установите SO_SNDLOWAT на 100 и попытаетесь отправить 200 байтов, он должен по крайней мере принять 100 байтов данных, он может принять больше, вплоть до целых 200 байтов, а также любое значение от 100 до 200, но не меньшечем 100. Имейте в виду, значение по умолчанию SO_SNDLOWAT равно 1, и это также поведение по умолчанию неблокирующего сокета (он должен принять по крайней мере 1 байт или потерпеть неудачу с EWOULDBLOCK)

    Обратите внимание, что UDP-сокеты всегда "все или ничего", они никогда не принимают только "часть данных", поэтому настройка SO_SNDLOWAT относится только к TCP-сокетам, которые могут принимать только часть предлагаемых данных.

  2. Если сокет блокируется, настройка SO_SNDLOWAT не оказывает реального влияния на вызов send(), так как в этом случае сокет всегда будет принимать все данные или будет блокировать изатем он будет блокироваться до тех пор, пока не будут приняты все данные или не истечет тайм-аут отправки (если тайм-аут отправки был установлен с помощью SO_SNDTIMEO или базовый протокол имеет собственный тайм-аут для отправки).

  3. Независимо от того, соцКэт блокирует или нет, независимо от того, является ли он UDP или TCP, вызов poll() или select() будет утверждать, что этот сокет доступен для записи, только если вызов send() может принять как минимум SO_SNDLOWAT байтов.

Так для чего этот вариант действительно хорош?Обычно это используется для того, чтобы ваш процесс не передавал данные побайтно после того, как буфер сокета запустился, но при больших блоках, как при поведении по умолчанию, select() и poll() скажут, что сокет доступен для записи, даже если простоместо для одного байта в буфере сокета.Другими словами, это всего лишь оптимизация производительности, поскольку код, который работает правильно с произвольной записью в сокет, будет работать правильно, независимо от того, установлен ли SO_SNDLOWAT, и независимо от того, какое значение может потребоваться, если в некоторых экстремальных ситуациях ему просто понадобится намного меньше процессорного времени1047 * имеет разумное значение.Но, как и во всех настройках производительности, если вы не знаете точно, что делаете, вы можете легко ухудшить ситуацию, задав неправильные значения, поэтому, если сомневаетесь, не трогайте этот параметр.

1 голос
/ 24 ноября 2011

Афаик, второй правильный, но я так и не смог его использовать.

SO_SNDLOWAT нельзя изменить в Linux.setsockopt завершается с ошибкой ENOPROTOOPT

1 голос
/ 23 ноября 2011

Первое описание является правильной интерпретацией.

Что касается влияния невозможности установить SO_SNDLOWAT, я не думаю, что это будет иметь значение, поскольку производительность зависит от таких вещей, как алгоритм Nagle, обнаружение пути-MTU и т. Д. Я подозреваю, что другие реализации TCP / IP молчаливо игнорировать эту опцию.

...