Ответ 1
Один поток для каждого соединения плохой дизайн (не масштабируемый, слишком сложный), но, к сожалению, слишком распространенный.
Сервер сокетов работает примерно так:
- Слуховой сокет настроен для приема соединений и добавлен в socketset
- Набор сокетов проверяется на события
- Если у прослушивающего сокета есть ожидающие подключения, новые сокеты создаются путем приема соединений, а затем добавляются в набор сокетов
- Если подключенный сокет имеет события, соответствующие функции ввода-вывода называются
- Набор сокетов снова проверяется на события.
Это происходит в одном потоке, вы можете легко обрабатывать тысячи подключенных сокетов в одном потоке, и есть несколько веских причин сделать это более сложным, введя потоки.
while running
select on socketset
for each socket with events
if socket is listener
accept new connected socket
add new socket to socketset
else if socket is connection
if event is readable
read data
process data
else if event is writable
write queued data
else if event is closed connection
remove socket from socketset
end
end
done
done
IP-стек позаботится обо всех деталях, по которым пакеты переходят в "сокет" в каком порядке. С точки зрения приложений сокет представляет собой надежный упорядоченный поток байтов (TCP) или ненадежную неупорядоченную последовательность пакетов (UDP)
РЕДАКТИРОВАТЬ: В ответ на обновленный вопрос.
Я не знаю ни одной из библиотек, которые вы упомянули, но о тех понятиях, которые вы упомянули:
- Кэш сеанса обычно хранит данные, связанные с клиентом, и может повторно использовать эти данные для нескольких соединений. Это имеет смысл, когда логика приложения требует информации о состоянии, но это уровень выше, чем фактический конец сети. В приведенном выше примере кеш сеанса будет использоваться частью "данных процесса".
- Буферные пулы - также простая и часто эффективная оптимизация сервера с высоким трафиком. Концепцию очень легко реализовать, вместо того, чтобы выделять/освобождать место для хранения данных, которые вы читаете/записываете, вы извлекаете предварительно выделенный буфер из пула, используете его, а затем возвращаете его в пул. Это позволяет избежать (иногда относительно дорогостоящих) механизмов выделения/освобождения бэкэнда. Это напрямую не связано с сетью, вы также можете использовать буферные пулы, например. то, что читает куски файлов и обрабатывает их.