Как идентифицируются клиенты (клиентские сокеты)?

в моем понимании serverSocket = new ServerSocket(portNumber) мы создаем объект, который потенциально может "прослушивать" указанный порт. By clientSocket = serverSocket.accept() мы заставляем сокет сервера " слушать "его порт и" принимать " соединение от любого клиента, который пытается подключиться к серверу через порт, связанный с сервером. Когда я говорю "клиент пытается подключиться к серверу", я имею в виду, что клиентская программа выполняет"nameSocket = new Socket(serverIP, serverPort)".

Если клиент пытается подключиться к сервер, сервер "принимает" этот клиент (т. е. создает "клиентский сокет", связанный с этим клиентом).

Если новый клиент пытается подключиться к серверу, сервер создает новый сокет Client (связанные с новым клиентом). Но как сервер узнает, является ли он" новым "клиентом или" старым", у которого уже есть сокет? Или, другими словами, как идентифицируются клиенты? По их IP? По их IP и Порту? Какими-то "подписями"?

что произойдет, если "старый" клиент пытается использовать сокет(IP-адресов сервера,IP-адресов сервера) снова? Будет ли сервер создавать второй сокет, связанный с этим клиентом?

5 ответов


сервер прослушивает адрес и порт. Например, IP-адрес сервера 10.0.0.1, и он прослушивает порт 8000.

ваш IP-адрес клиента-10.0.0.2, и клиент "подключается" к серверу на порту 10.0.0.1 8000. В TCP-соединении вы указываете порт сервера, к которому хотите подключиться. Ваш клиент получит свой собственный номер порта, но вы не контролируете это, и он будет отличаться для каждого подключения. Клиент выбирает сервер порт, к которому он хочет подключиться, а не клиент порт, с которого он соединяется.

например, при первом подключении ваш клиент может получить порт на стороне клиента 12345. Он подключается от порта 10.0.0.2 12345 к порту сервера 10.0.0.1 8000. Ваш сервер может видеть, с какого порта клиент подключается, вызывая getpeername на своей стороне соединения.

когда клиент подключается во второй раз, номер порта будет будь другим, скажем, порт 12377. Сервер может увидеть это, вызвав getpeername на втором соединении - он увидит другой номер порта на стороне клиента. (getpeername также показывает IP-адрес клиента.)

кроме того, каждый раз, когда вы вызываете accept на сервере, вы получаете новый сокет. У вас все еще есть исходное прослушивание сокета, и на каждом accept вы получаете новый сокет. Вызовите getpeername в принятом сокете, чтобы узнать, с какого клиентского порта происходит соединение. Если два клиенты подключаются к вашему серверу, теперь у вас есть три сокета-оригинальный прослушивающий сокет и сокеты каждого из двух клиентов.

вы можете иметь много клиентов, подключенных к тому же серверу порт 8000 в то же время. И многие клиенты могут быть подключены из одного порта клиента (например, порт 12345), только не с одного IP-адреса. С того же IP-адреса клиента, например 10.0.0.2, каждое соединение клиента с портом сервера 8000 будет от уникального порта клиента, например 12345, 12377, и т. д. Вы можете отличить клиентов по их комбинации IP-адреса и порта.

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

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


каждое TCP-соединение имеет идентификатор quadruple (порт src, адрес src, порт dest, адрес dest).

всякий раз, когда ваш сервер принимает новых клиентов, новый Socket создается, и он независим от каждого другого сокета, созданного до сих пор. Идентификации клиентов не implictly каким-либо образом обработаны..

вам не нужно думать, что сокеты связаны с "клиентами", они связаны с ip и портом, но нет прямой корреляции между этими двумя.

если тот же клиент пытается открыть другой сокет, создав новый, у вас будут два несвязанных сокета (потому что порты будут отличаться наверняка). Это потому, что клиент не может использовать один и тот же порт для открытия нового соединения, поэтому учетверенный будет другим, тем же ip-адресом клиента, тем же ip-адресом сервера, тем же портом сервера, но другим портом клиента.

редактировать для ваших вопросов:

  1. клиенты не указывают порт, потому что он случайным образом выбирается из свободных (> 1024, если я не ошибаюсь) из базовой операционной системы
  2. соединение не может быть открыто от клиента, использующего тот же порт, операционная система не позволит вам сделать это (на самом деле вы не указываете никакого порта вообще), и в любом случае он скажет вам, что порт уже привязан к сокету, поэтому эта проблема не может произойти.
  3. всякий раз, когда сервер получает новый запрос на подключение, он считается новым, потому что также, если ip тот же порт будет отличаться наверняка (в случае повторной отправки старого пакета или подобных предостережений я думаю, что запрос будет отброшен)

кстати все эти ситуации четко объясняются в TCP RFC здесь.


по определению, это не вопрос, связанный с Java, а о сети в целом, поскольку сокеты и SeverSockets применяются к любому языку программирования с поддержкой сети.

сокет ограничен локальным портом. Клиент откроет соединение с сервером (по операционной системе / драйверам / адаптерам / оборудованию/линии/.../ линия / оборудование / адаптеры / драйверы / серверная ОС). Это "соединение" выполняется протоколом, называемым IP (Internet Protocol), когда вы подключены к Интернет. Когда вы используете "сокеты", он будет использовать другой протокол, который является TCP/IP-протоколом.

Интернет-протокол будет идентифицировать узлы в сети двумя вещами: их IP-адрес и их порт. TCP / IP-протокол будет отправлять сообщения, используя IP, и убедитесь, что сообщения правильно получены.

сейчас, отвечая на ваш вопрос: все зависит! Это зависит от ваших драйверов, адаптеров, вашего оборудования, вашей линии. При подключении к компьютеру localhost вы не получит дальше, чем адаптер. Аппаратное обеспечение не требуется, так как данные фактически не передаются по линии. (Хотя часто вам нужно оборудование, прежде чем вы сможете иметь адаптер.)

по определению, Интернет-протокол определяет соединение как пару узлов (таким образом, четыре вещи: два IP-адреса и два порта). Кроме того, Интернет-протокол определяет, что один узел может использовать только один порт за раз, чтобы инициировать соединение с другим узлом (Примечание: это относится только к клиенту, а не сервер.)

чтобы ответить на ваш второй вопрос: если есть два сокета: "новый" и "старый". Поскольку, по интернет-протоколу, соединение представляет собой пару узлов, а узлы могут использовать только один порт за раз для соединения, порты "новый" и "старый" должны быть разные. И поскольку это отличается, "новый" клиент может быть отличен от "старого", так как номер порта отличается.


Я думаю, что вопрос здесь в том, почему вас волнует, является ли клиент новым или старым. Что такое новое и старое? Например, веб-браузер может подключиться к веб-серверу для запроса веб-страницы. Это создаст соединение so serverSocket.accept() возвращает новый Socket. Затем соединение закрывается веб-браузером.

Afer пару минут, конец используется нажмите на ссылку на веб-странице и браузер запросить новую страницу на сервер. Это создаст соединение so serverSocket.accept() вернет a новый Socket.

теперь веб-серверу все равно, является ли это новым или старым клиентом. Ему просто нужно сервер запрошенной страницы. Если сервер do забота если "клиент" уже запросил страницу в прошлом, он должен сделать это, используя некоторую информацию в протоколе, используемом на сокете. Проверьтеhttp://en.wikipedia.org/wiki/OSI_model В этом случае ServerSocket и Socket ack на транспортном уровне. Вопрос "этот клиент уже запросил страницу на сервере " должна быть дана информация о сеансе или даже уровне приложения.

в примере веб-браузера / сервера протокол http (который является приложением) содержит информацию о том, кто является этим браузером в параметрах запроса (браузер передает информацию cookie с каждым запросом). Затем http-сервер может установить / прочитать информацию cookie в known, если браузер подключен до и в конечном итоге поддерживает сеанс на стороне сервера для этого браузер.

Итак, вернемся к вашему вопросу: Почему вас волнует, новый это или старый клиент?


сокет идентифицируется:

(локальный IP, локальный порт, удаленный IP, Удаленный порт, протокол IP (UDP / TCP/SCTP / etc.)

и это информация, которую ОС использует для сопоставления пакетов / данных с правым дескриптором / файловым дескриптором вашей программы. Для некоторых видов сокетов(например, не подключенного UDP-сокета)удаленный порт/удаленный IP-адрес могут быть подстановочными знаками.