Как работает асинхронный сервер сокетов?

Я должен указать, что я не спрашиваю о конкретных деталях реализации (пока), а просто общий обзор того, что происходит. Я понимаю основную концепцию сокета и нуждаюсь в разъяснении процесса в целом. Мое (возможно, очень неправильное) понимание в настоящее время таково:

Сокет постоянно прослушивает клиентов, которые хотят подключиться (в своем потоке). Когда происходит соединение, возникает событие, которое порождает другой поток для выполнения процесса соединения. Во время процесса подключения клиенту присваивается собственный сокет, в котором для связи с сервером. Затем сервер ожидает данных от клиента и при получении данных происходит событие, которое порождает поток для чтения данных из потока в буфер.

Мои вопросы:

Как вышло мое понимание?

Требуется ли каждому клиентскому сокету собственный поток для прослушивания данных?

Как перенаправляются данные в правильный клиентский сокет? Это чему-то позаботятся кишки TCP/UDP/kernel?

В этой многопоточной среде какие данные обычно используются совместно, и в чем суть споров?

Любые разъяснения и дополнительное объяснение будут очень признательны.

EDIT:

Что касается вопроса о том, какие данные обычно используются совместно, а также о точках споров, я понимаю, что это больше детализация реализации, чем вопрос об общем процессе приема соединений и отправки/получения данных. Я просмотрел несколько реализаций (SuperSocket и Kayak) и заметил некоторую синхронизацию для таких вещей, как кеш сеанса и многоразовые буферные пулы. Не стесняйтесь игнорировать этот вопрос. Я оценил все ваши отзывы.

Ответ 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)

РЕДАКТИРОВАТЬ: В ответ на обновленный вопрос.

Я не знаю ни одной из библиотек, которые вы упомянули, но о тех понятиях, которые вы упомянули:

  • Кэш сеанса обычно хранит данные, связанные с клиентом, и может повторно использовать эти данные для нескольких соединений. Это имеет смысл, когда логика приложения требует информации о состоянии, но это уровень выше, чем фактический конец сети. В приведенном выше примере кеш сеанса будет использоваться частью "данных процесса".
  • Буферные пулы - также простая и часто эффективная оптимизация сервера с высоким трафиком. Концепцию очень легко реализовать, вместо того, чтобы выделять/освобождать место для хранения данных, которые вы читаете/записываете, вы извлекаете предварительно выделенный буфер из пула, используете его, а затем возвращаете его в пул. Это позволяет избежать (иногда относительно дорогостоящих) механизмов выделения/освобождения бэкэнда. Это напрямую не связано с сетью, вы также можете использовать буферные пулы, например. то, что читает куски файлов и обрабатывает их.

Ответ 2

Как вышло мое понимание?

Довольно далеко.

Требуется ли каждому клиентскому сокету собственный поток для прослушивания данных?

Нет.

Как перенаправляются данные в правильный клиентский сокет? Это чему-то позаботятся кишки TCP/UDP/kernel?

TCP/IP - это несколько уровней протокола. Там нет "ядра". Это куски, каждый с отдельным API для других частей.

IP-адрес обрабатывается на месте.

Порт # обрабатывается в другом месте.

IP-адреса сопоставляются с MAC-адресами для идентификации конкретного хоста. Порт # - это то, что связывает сокет TCP (или UDP) с определенной частью прикладного программного обеспечения.

В этой многопоточной среде какие данные обычно используются совместно, и в чем суть споров?

Какая потоковая среда?

Обмен данными? Что?

Разногласия? Физический канал является точкой состязания номер один. (Ethernet, например, зависит от обнаружения столкновений.) После этого, всякая часть компьютерной системы является ограниченным ресурсом, разделяемым несколькими приложениями, и является предметом спора.