Как несколько клиентов одновременно подключаются к одному порту, например 80, на сервере?

Я понимаю основы работы портов. Однако я не понимаю, как несколько клиентов могут одновременно подключаться к порту 80. Я знаю, что каждый клиент имеет уникальный (для своего компьютера) порт. Отвечает ли сервер обратно с доступного порта клиенту и просто заявляет, что ответ пришел с 80? Как это работает?

5 Solutions collect form web for “Как несколько клиентов одновременно подключаются к одному порту, например 80, на сервере?”

Во-первых, «порт» – это просто номер. Все «соединение с портом» действительно представляет собой пакет, который имеет этот номер, указанный в поле заголовка «порт назначения».

Теперь на ваш вопрос есть два ответа: один для протоколов с поддержкой состояния и один для протоколов без состояния.

Для протокола без учета состояния (то есть UDP) нет проблем, потому что «соединений» не существует – несколько человек могут отправлять пакеты на один и тот же порт, и их пакеты будут поступать в любую последовательность. Никто никогда не находится в «связанном» состоянии.

Для протокола с состоянием (например, TCP) соединение идентифицируется 4-кортежем, состоящим из портов источника и получателя, а также IP-адресов источника и получателя. Таким образом, если две разные машины подключаются к одному и тому же порту на третьем компьютере, существуют два разных соединения, поскольку исходные IP-адреса различаются. Если один и тот же компьютер (или два за NAT или иным образом использует один и тот же IP-адрес) соединяется дважды с одним удаленным концом, соединения дифференцируются через порт источника (который обычно представляет собой случайный порт с высоким номером).

Просто, если я подключусь к одному и тому же веб-серверу дважды от своего клиента, у двух соединений будут разные исходные порты из моих перспективных и целевых портов с веб-сервера. Таким образом, нет никакой двусмысленности, хотя оба соединения имеют одинаковые IP-адреса источника и назначения.

Порты – это способ мультиплексирования IP-адресов, чтобы разные приложения могли прослушивать одну и ту же пару IP-адресов / протоколов. Если приложение не определяет собственный протокол более высокого уровня, нет возможности мультиплексировать порт. Если два соединения с использованием одного и того же протокола одновременно имеют одинаковые IP-адреса источника и получателя и идентичные исходные и целевые порты, они должны быть одинаковыми.

Важный:

Мне жаль говорить, что ответ «Бореалид» является неточным и несколько неправильным – во-первых, нет никакого отношения к состоянию или безгражданству, чтобы ответить на этот вопрос, и, самое главное, определение кортежа для сокета неверно.

Сначала запомните ниже два правила:

  1. Первичный ключ сокета: сокет идентифицируется {SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL} не {SRC-IP, SRC-PORT, DEST-IP, DEST-PORT} – Протокол является важной частью определения сокета.

  2. Отображение OS Process & Socket: процесс может быть связан с (может открыть / может слушать) несколько сокетов, что может быть очевидным для многих читателей.

Пример 1: Два клиента, подключающиеся к одному серверному порту, означают: socket1 {SRC-A, 100, DEST-X,80, TCP} и socket2{SRC-B, 100, DEST-X,80, TCP} . Это означает, что хост A подключается к порту 80 сервера X, а другой узел B также подключается к одному серверу X к тому же порту 80. Теперь, как сервер обрабатывает эти два сокета, зависит от того, является ли сервер однопоточным или многопоточным (я буду объясните это позже). Важно то, что один сервер может одновременно прослушивать несколько сокетов.

Чтобы ответить на исходный вопрос:

Независимо от протоколов состояния или состояния, два клиента могут подключаться к одному серверному порту, потому что для каждого клиента мы можем назначить другой сокет (поскольку клиентский IP-адрес определенно будет отличаться). Один и тот же клиент может также иметь два сокета, подключающихся к одному серверному порту, поскольку такие сокеты отличаются SRC-PORT . Со всей справедливостью «Borealid» по сути упомянул тот же правильный ответ, но ссылка на state-less / full была вроде ненужной / запутанной.

Чтобы ответить на вторую часть вопроса о том, как сервер знает, какой сокет должен отвечать. Сначала поймите, что для одного сервера, который слушает один и тот же порт, может быть более одного сокета (может быть от одного клиента или от разных клиентов). Теперь, пока сервер знает, какой запрос связан с каким сокетом, он всегда может отвечать на соответствующий клиент, используя тот же сокет. Таким образом, серверу никогда не нужно открывать другой порт в своем собственном узле, чем исходный, на котором клиент первоначально пытался связать соединение. Если какой-либо сервер выделяет разные серверные порты после привязки сокета, то, на мой взгляд, сервер тратит впустую свой ресурс, и ему необходимо, чтобы клиент снова связал соединение с новым назначенным портом.

Еще немного для полноты:

Пример 2: Очень интересный вопрос, который может обрабатывать два разных процесса сервера одному порту. Если вы не рассматриваете протокол как один из определяющих параметр сокетов, тогда ответ будет отрицательным. Инициативно это происходит потому, что мы можем сказать, что в таком случае для одного клиента, пытающегося подключиться к серверному порту, не будет никакого механизма, чтобы упомянуть, какой из двух процессов прослушивания намеревается клиент. Это та же тема, что и правило (2). Однако это WRONG ответ, потому что «протокол» также является частью определения сокета. Таким образом, два процесса в одном узле могут прослушивать один и тот же порт только в том случае, если они используют другой протокол. Например, два несвязанных клиента (например, один использует TCP, а другой использует UDP) могут связывать соединение и связь с одним и тем же узлом сервера и с одним и тем же портом, но они должны обслуживаться двумя различными серверными процессами.

Типы серверов – одно и несколько:

Когда процессы сервера, прослушивающие порт, который означает несколько сокетов, могут одновременно подключаться и взаимодействовать с одним и тем же серверным процессом. Если сервер использует только один дочерний процесс для обслуживания всех сокетов, тогда сервер называется однопроцессорным / streamовым, и если сервер использует много subprocessов для обслуживания каждого сокета одним subprocessом, тогда сервер называется мульти- процесс / поточный сервер. Обратите внимание, что независимо от типа сервера сервер может / должен всегда использовать один и тот же исходный сокет для ответа (нет необходимости выделять другой сервер-порт).

Рекомендуемые книги и остальные два тома, если можно.

Примечание о родительском / дочернем процессе (в ответ на запрос / комментарий «Иоанан Александру Куку»)

Где бы я ни упоминал какую-либо концепцию в отношении двух процессов, скажем, A и B, считают, что они не связаны родительскими отношениями с дочерними элементами. ОС (особенно UNIX) по дизайну позволяют дочернему процессу наследовать все файлы-дескрипторы (FD) от родителей. Таким образом, все сокеты (в UNIX, подобные ОС, также являются частью FD), что прослушивание процесса прослушивается многими другими процессами A1, A2, .. если они связаны отношением parent-child к A. Но независимый процесс B (т.е. не имеющий отношения родитель-ребенок к A) не может прослушивать один и тот же сокет. Кроме того, также обратите внимание, что это правило запрещения двух независимых процессов для прослушивания одного и того же сокета лежит на ОС (или ее сетевых библиотеках), и, к тому же, это выполняется большинством ОС. Тем не менее, можно создать собственную ОС, которая вполне может нарушить эти ограничения.

Прослушивание TCP / HTTP в портах: как многие пользователи могут использовать один и тот же порт

Итак, что происходит, когда сервер прослушивает входящие соединения на TCP-порт? Например, предположим, что у вас есть веб-сервер на порту 80. Предположим, что ваш компьютер имеет общеansible IP-адрес 24.14.181.229, а человек, пытающийся подключиться к вам, имеет IP-адрес 10.1.2.3. Этот человек может подключиться к вам, открыв сокет TCP до 24.14.181.229:80. Достаточно просто.

Интуитивно (и ошибочно), большинство людей считают, что это выглядит примерно так:

  Local Computer | Remote Computer -------------------------------- :80 | :80 ^^ not actually what happens, but this is the conceptual model a lot of people have in mind. 

Это интуитивно понятно, потому что с точки зрения клиента он имеет IP-адрес и подключается к серверу через IP: PORT. Поскольку клиент подключается к порту 80, то его порт должен быть тоже 80? Это разумная вещь, чтобы думать, но на самом деле не то, что происходит. Если бы это было правильно, мы могли обслуживать только одного пользователя на чужой IP-адрес. Как только удаленный компьютер подключится, он будет подключать порт 80 к порту 80, и никто не сможет подключиться.

Необходимо понять три вещи:

1.) На сервере процесс прослушивает порт. Как только он получает соединение, он передает его в другой stream. Связь никогда не заставляет прослушивающий порт.

2.) Соединения уникально идентифицируются ОС следующим 5-кортежем: (локальный-IP-адрес, локальный порт, удаленный IP-протокол, удаленный порт, протокол). Если какой-либо элемент в кортеже отличается, то это полностью независимое соединение.

3.) Когда клиент подключается к серверу, он выбирает случайный неиспользуемый порт источника высокого порядка . Таким образом, один клиент может иметь до ~ 64 к подключений к серверу для одного и того же порта назначения.

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

  Local Computer | Remote Computer | Role ----------------------------------------------------------- 0.0.0.0:80 |  | LISTENING 127.0.0.1:80 | 10.1.2.3: | ESTABLISHED 

Глядя на то, что на самом деле происходит

Во-первых, давайте использовать netstat, чтобы узнать, что происходит на этом компьютере. Мы будем использовать порт 500 вместо 80 (потому что на порту 80 происходит целая куча вещей, поскольку это общий порт, но функционально это не имеет значения).

  netstat -atnp | grep -i ":500 " 

Как и ожидалось, вывод пуст. Теперь давайте запустим веб-сервер:

  sudo python3 -m http.server 500 

Теперь вот результат запуска netstat:

  Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN - 

Итак, теперь есть один процесс, который активно прослушивает (State: LISTEN) на порту 500. Локальный адрес 0.0.0.0, который является кодом для «прослушивания всех». Простая ошибка заключается в прослушивании адреса 127.0.0.1, который будет принимать только соединения с текущего компьютера. Таким образом, это не соединение, это просто означает, что процесс запросил привязать () к IP-порту, и этот процесс отвечает за обработку всех подключений к этому порту. Это указывает на ограничение того, что на компьютере может быть только один процесс, который прослушивает порт (есть способы обойти это с использованием мультиплексирования, но это гораздо более сложная тема). Если веб-сервер прослушивает порт 80, он не может совместно использовать этот порт с другими веб-серверами.

Итак, давайте подключим пользователя к нашей машине:

  quicknet -m tcp -t localhost:500 -p Test payload. 

Это простой скрипт ( https://github.com/grokit/dcore/tree/master/apps/quicknet ), который открывает сокет TCP, в этом случае отправляет полезную нагрузку («тестовая нагрузка»), ждет несколько секунд и отключается. Выполнение netstat снова, пока это происходит, отображает следующее:

  Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN - tcp 0 0 192.168.1.10:500 192.168.1.13:54240 ESTABLISHED - 

Если вы подключитесь к другому клиенту и снова выполните netstat, вы увидите следующее:

  Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN - tcp 0 0 192.168.1.10:500 192.168.1.13:26813 ESTABLISHED - 

… то есть клиент использовал другой случайный порт для соединения. Поэтому между IP-адресами никогда не возникает путаницы.

Обычно для каждого подключающегося клиента сервер создает дочерний процесс, который взаимодействует с клиентом (TCP). Родительский сервер передает дочернему процессу установленный сокет, который обменивается данными с клиентом.

Когда вы отправляете данные в сокет с вашего дочернего сервера, стек TCP в ОС создает пакет, возвращающийся к клиенту, и устанавливает «от порта» до 80.

Несколько клиентов могут подключаться к одному и тому же порту (скажем, 80) на сервере, потому что на стороне сервера после создания сокета и привязки (настройка локального IP и порта) в соке вызывается прослушивание, которое сообщает ОС принимать входящие соединения.

Когда клиент пытается подключиться к серверу на порту 80, вызов вызова вызывается в гнезде сервера. Это создает новый сокет для клиента, пытающегося подключиться, и аналогичные новые сокеты будут созданы для последующих клиентов, используя тот же порт 80.

Словами курсивом являются системные вызовы.

ссылка

http://www.scs.stanford.edu/07wi-cs244b/refs/net2.pdf

  • Java обнаруживает потерянное соединение
  • mySQL - создание новой таблицы с использованием данных и столбцов из трех таблиц
  • Строка подключения с относительным путем к файлу базы данных
  • Мгновенно обнаруживать отключение клиента от серверного сокета
  • Загрузка JSON с NSURLSession не возвращает никаких данных
  • Почему при запуске URL-адреса возникает исключение «java.net.ConnectException: Connection timed out»?
  • Запустить командный файл с командой psql без пароля
  • Соединение RMI отказалось на localhost
  • java.rmi.ConnectException: подключение отказалось от хоста: 127.0.1.1;
  • Давайте будем гением компьютера.