На низком уровне сокеты - это просто сокеты, независимо от того, используются ли они в серверном или клиентском приложении. Разница между ними заключается в системных вызовах каждого типа приложений.
Серверные сокеты будут вызывать bind()
для связи с портом. Они хотят быть связанными с портом, чтобы другие программы знали, где их найти. Клиентские сокеты могут звонить bind()
, но почти никогда не делают, потому что нет особого смысла. Если сокет не вызывает bind()
, ОС просто выберет для него временный порт, что хорошо для клиентов, потому что они выполняют вызов; никому не нужно , чтобы звонить им.
Серверные сокеты вызывают listen()
. Это было хорошо объяснено в других ответах.
Серверные сокеты вызывают accept()
, и я думаю, что это суть вашего вопроса, потому что сначала он немного загадочный. Важно понять, что при вызове accept()
ядро передаст обратно новый сокет. Теперь он отделен от исходного сокета прослушивания и используется вашим сервером для связи со своими партнерами.
Ключ к пониманию того, как прослушивающий сокет продолжает слушать, пока принятое соединение делает свое дело, заключается в понимании того, что соединения tcp зависят от 4-х наборов (1) локального адреса (2) локального порта (3) внешнего адреса (4) иностранный порт. Они определяют уникальную связь. Перед тем, как accept()
передал обратно новый сокет, ядро использовало эти значения для создания различных структур, так что в сотрудничестве со стеком tcp / ip весь трафик с этим кортежем будет направляться в подключенный сокет. Даже если ваш сервер может иметь тысячу соединений с локальным адресом 192.168.1.100, порт 80, клиентская комбинация адреса и порта всегда будет отличаться, и, следовательно, кортеж всегда уникален.