В последнее время я исследовал ряд сетевых библиотек и фреймворков, таких как libevent, libev, Facebook Tornado и Concurrence (Python).
Одна вещь, которую я заметил в их реализациях, - это использование буферов чтения / записи на уровне приложения для каждого клиента (например, IOStream в Tornado) - даже HAProxy имеет такие буферы.
В дополнение к этим буферам уровня приложения существуют буферы реализации TCP ядра ОС для каждого сокета.
Я могу понять, как app / lib использует буфер чтения, я думаю: app / lib читает из буфера ядра в буфер приложения, и приложение что-то делает с данными (например, десериализует сообщение в нем).
Однако я запутался в необходимости / использовании буфера записи. Почему бы просто не записать в буфер отправки / записи ядра? Чтобы избежать накладных расходов на системные вызовы (запись)? Я полагаю, дело в том, чтобы быть готовым с большим количеством данных, которые нужно отправить в буфер записи ядра, когда ядро уведомляет приложение / библиотеку о том, что сокет "доступен для записи" (например, EPOLLOUT). Но почему бы просто не избавиться от буфера записи приложения и не настроить буфер записи TCP ядра таким же большим?
Также рассмотрите сервис, для которого имеет смысл отключение алгоритма Нэгла (например, игровой сервер). В такой конфигурации, я полагаю, мне хотелось бы обратного: не было буфера записи ядра, но был буфер записи приложения, да? Когда приложение готово к отправке полного сообщения, оно записывает буфер приложения через send () и т. Д., А ядро передает его.
Помогите мне прояснить мне это понимание, если хотите. Спасибо!