API сокетов является стандартом де-факто для связи TCP/IP и UDP/IP (т.е. сетевого кода, как мы его знаем). Однако одна из его основных функций accept()
немного волшебна.
Заимствовать полуформальное определение:
accept() используется на стороне сервера. Он принимает полученную входящую попытку для создания нового TCP-соединения из удаленный клиент и создает новый сокет, связанный с гнездом адресную пару этого соединения.
Другими словами, accept
возвращает новый сокет, через который сервер может связываться с недавно подключенным клиентом. Старый сокет (на котором был вызван accept
) остается открытым на том же порту, слушая новые соединения.
Как работает accept
? Как это реализовано? Там много путаницы по этой теме. Многие люди утверждают, что он открывает новый порт, и вы общаетесь с ним через клиента. Но это, очевидно, неверно, поскольку новый порт не открывается. Вы действительно можете общаться через один и тот же порт с разными клиентами, но как? Когда несколько потоков называют recv
на одном и том же порту, как данные знают, куда идти?
Я предполагаю, что что-то похожее на адрес клиента связано с дескриптором сокета, и всякий раз, когда данные поступают через recv
, он направляется в правильный сокет, но я не уверен.
Было бы здорово получить подробное объяснение внутренней работы этого механизма.