Влияние производительности использования write() вместо send() при записи в сокет
Я работаю над написанием сетевого приложения на С++ на платформе Linux с использованием обычного API сокетов, и я рассматриваю два альтернативных способа записи байтового массива в поток TCP: либо путем вызова write(), либо путем вызов send(). Я знаю, что, поскольку это Linux, дескриптор сокета - это просто дескриптор файла, и поэтому он действителен для выполнения вызовов read() и write() в сокете, однако API сокетов также предоставляет send() и recv ( ) для выполнения тех же задач.
Поэтому я задаюсь вопросом, есть ли какая-то особая причина выбора одного класса функций над другим - функции send/recv, оптимизированные для записи/чтения в сети, работают ли они лучше и т.д.? Или это действительно произвольно, какие функции я использую? Должны ли читать() и write() вести себя правильно во всех случаях?
Спасибо за любые идеи!
Ответы
Ответ 1
Не должно быть разницы. Цитирование из man 2 send
:
Единственное различие между send()
и write()
- наличие флагов. С параметром нулевых флагов send()
эквивалентен write()
.
Пока вы не хотите указывать и флаги для send()
, вы можете свободно использовать write()
.
Ответ 2
recv
и send
позволяют указывать флаги, например, для внеполосных пакетов. Если вам не нужно указывать флаги, read
и write
вполне адекватны.
Ответ 3
write
v.s. send
для одного байта, или один массив, вероятно, не будет сильно отличаться - они скоро закончат один и тот же путь кода (в конечном счете они выполняют ту же операцию). Накладные расходы на передачу сети вряд ли будут на этом уровне; это будет фактическое соединение TCP и перемещение бит по проводам.
Однако, если вы намереваетесь отправлять большие многостраничные сообщения за один раз, вы должны посмотреть на sendmsg()
syscall - это позволяет вам указать список несмежных массивов данных для отправки.
В конце дня применяются обычные правила - сначала напишите заявку, затем проверьте, где ваши узкие места.