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

Влияние производительности использования write() вместо send() при записи в сокет

Я работаю над написанием сетевого приложения на С++ на платформе Linux с использованием обычного API сокетов, и я рассматриваю два альтернативных способа записи байтового массива в поток TCP: либо путем вызова write(), либо путем вызов send(). Я знаю, что, поскольку это Linux, дескриптор сокета - это просто дескриптор файла, и поэтому он действителен для выполнения вызовов read() и write() в сокете, однако API сокетов также предоставляет send() и recv ( ) для выполнения тех же задач.

Поэтому я задаюсь вопросом, есть ли какая-то особая причина выбора одного класса функций над другим - функции send/recv, оптимизированные для записи/чтения в сети, работают ли они лучше и т.д.? Или это действительно произвольно, какие функции я использую? Должны ли читать() и write() вести себя правильно во всех случаях?

Спасибо за любые идеи!

4b9b3361

Ответ 1

Не должно быть разницы. Цитирование из man 2 send:

Единственное различие между send() и write() - наличие флагов. С параметром нулевых флагов send() эквивалентен write().

Пока вы не хотите указывать и флаги для send(), вы можете свободно использовать write().

Ответ 2

recv и send позволяют указывать флаги, например, для внеполосных пакетов. Если вам не нужно указывать флаги, read и write вполне адекватны.

Ответ 3

write v.s. send для одного байта, или один массив, вероятно, не будет сильно отличаться - они скоро закончат один и тот же путь кода (в конечном счете они выполняют ту же операцию). Накладные расходы на передачу сети вряд ли будут на этом уровне; это будет фактическое соединение TCP и перемещение бит по проводам.

Однако, если вы намереваетесь отправлять большие многостраничные сообщения за один раз, вы должны посмотреть на sendmsg() syscall - это позволяет вам указать список несмежных массивов данных для отправки.

В конце дня применяются обычные правила - сначала напишите заявку, затем проверьте, где ваши узкие места.