PassFront
  1. PassFront
  2. База знаний
  3. Модели OSI и TCP/IP

Что такое порт и сокет и как ОС различает соединения?

Модели OSI и TCP/IP

Порт — 16-битный номер (0–65535), адресующий приложение внутри хоста; сокет — объект ОС, конечная точка соединения. TCP-соединение однозначно задаёт четвёрка: IP и порт клиента, IP и порт сервера.

Порты

  • 0–1023 — well-known (22, 80, 443), на Linux для bind нужны привилегии.
  • 1024–49151 — registered: 5432 у PostgreSQL, 6379 у Redis.
  • Эфемерные выдаёт ОС для исходящих соединений; в Linux по умолчанию 32768–60999.

Слушающий и подключённые сокеты

  • Сервер делает bind и listen на 8080 — это один listening-сокет.
  • Каждый accept возвращает новый сокет со своим 4-tuple, и у всех локальный порт 8080. Поэтому один порт обслуживает сотни тысяч клиентов.
  • Ядро ищет сокет по точному совпадению 4-tuple, а новые SYN отдаёт слушающему.
// сырых сокетов в браузере нет, но видно, открывал ли запрос новое соединение
for (const url of ['/api/a', '/api/b']) await fetch(url).then((r) => r.text()); // запись — после чтения тела
for (const e of performance.getEntriesByType('resource')) {
  if (!e.connectStart) continue; // чужой origin без Timing-Allow-Origin — нули
  const reused = e.connectStart === e.connectEnd; // не было TCP/TLS-рукопожатия
  console.log(e.name, e.nextHopProtocol, reused ? 'старый сокет' : 'новый сокет');
}

Граничные случаи

  • К одному IP:порт можно открыть не больше ~28 тыс. исходящих соединений — ephemeral port exhaustion без пула.
  • TIME_WAIT держит 4-tuple занятым ~60 с после закрытия.

Коротко для собеседования

Один порт сервера обслуживает множество клиентов, потому что ядро различает соединения по полной четвёрке адресов, а не по порту. Ограничения всплывают на клиенте: без пула соединений к одному хосту кончаются эфемерные порты, а TIME_WAIT держит их после закрытия.

Другие вопросы раздела