Как вы можете видеть в этом вопросе , который охватывает другие варианты сокетов, ответ зависит от операционной системы, поэтому оба ответа могут быть правильными, так как один является ответом из мира Linux, а другой -ответ из мира UNIX (BSD и Co).
В клонах BSD и BSD эта опция означает следующее:
Если сокет неблокируя и вызывая 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-сокетам, которые могут принимать только часть предлагаемых данных.
Если сокет блокируется, настройка SO_SNDLOWAT
не оказывает реального влияния на вызов send()
, так как в этом случае сокет всегда будет принимать все данные или будет блокировать изатем он будет блокироваться до тех пор, пока не будут приняты все данные или не истечет тайм-аут отправки (если тайм-аут отправки был установлен с помощью SO_SNDTIMEO
или базовый протокол имеет собственный тайм-аут для отправки).
Независимо от того, соцКэт блокирует или нет, независимо от того, является ли он UDP или TCP, вызов poll()
или select()
будет утверждать, что этот сокет доступен для записи, только если вызов send()
может принять как минимум SO_SNDLOWAT
байтов.
Так для чего этот вариант действительно хорош?Обычно это используется для того, чтобы ваш процесс не передавал данные побайтно после того, как буфер сокета запустился, но при больших блоках, как при поведении по умолчанию, select()
и poll()
скажут, что сокет доступен для записи, даже если простоместо для одного байта в буфере сокета.Другими словами, это всего лишь оптимизация производительности, поскольку код, который работает правильно с произвольной записью в сокет, будет работать правильно, независимо от того, установлен ли SO_SNDLOWAT
, и независимо от того, какое значение может потребоваться, если в некоторых экстремальных ситуациях ему просто понадобится намного меньше процессорного времени1047 * имеет разумное значение.Но, как и во всех настройках производительности, если вы не знаете точно, что делаете, вы можете легко ухудшить ситуацию, задав неправильные значения, поэтому, если сомневаетесь, не трогайте этот параметр.