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