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

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

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

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

Что происходит, если "старый" клиент пытается использовать Сокет (serverIP, serverIP) снова? Сервер создаст второй сокет, связанный с этим клиентом?

10
задан Jack 13 March 2010 в 19:18
поделиться

5 ответов

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

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

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

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

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

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

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

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

23
ответ дан 3 December 2019 в 15:51
поделиться

Каждое TCP-соединение имеет в качестве идентификатора четверку (src порт, адрес источника, порт назначения, адрес назначения) .

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

Вы не должны думать, что сокеты связаны с «клиентами», они связаны с IP-адресом и портом, но между ними нет прямой корреляции.

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

РЕДАКТИРОВАТЬ ваши вопросы:

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

Между прочим, все эти ситуации четко объяснены в TCP RFC здесь .

5
ответ дан 3 December 2019 в 15:51
поделиться

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

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

Теперь веб-серверу все равно, новый это клиент или старый. Ему просто нужно серверить запрошенную страницу. Если сервер действительно заботится о том, запрашивал ли «клиент» страницу в прошлом, он должен сделать это, используя некоторую информацию в протоколе, используемом в сокете. Ознакомьтесь с http://en.wikipedia.org/wiki/OSI_model В этом случае подтверждены ServerSocket и Socket на транспорте. уровень. На вопрос «запрашивал ли этот клиент уже страницу на сервере?» Следует ответить с помощью информации о сеансе или даже на уровне приложения.

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

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

0
ответ дан 3 December 2019 в 15:51
поделиться

Сокет идентифицируется следующим образом:

(локальный IP-адрес, локальный порт, удаленный IP-адрес, удаленный порт, IP-протокол (UDP / TCP / SCTP и т. Д.)

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

0
ответ дан 3 December 2019 в 15:51
поделиться

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

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

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

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

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

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

-1
ответ дан 3 December 2019 в 15:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: