Обнаружение конкретного клиента

#java #sockets #networking #chat

#java #сокеты #сеть #Чат

Вопрос:

Я разрабатываю приложение для общения в чате. У меня проблема. Как я могу обнаружить конкретного клиента поверх сервера?

Я использую классы ServerSocket и Socket для связи.

Комментарии:

1. На этот вопрос почти недостаточно информации для ответа. Ваш код должен отслеживать соединения и каким-то образом связывать их с клиентами. Все остальное зависит от вашего дизайна / кода.

Ответ №1:

Используйте getInetAddress() of Socket для получения адресов клиентов.

 Socket clientSocket = server.accept();
InetAddress clientAddress = clientSocket.getInetAddress();
  

Если у вас есть клиенты, уникальные для данного ip-адреса, вы можете сделать clientAddress.getHostAddress() , чтобы получить IP-адрес клиента.

Комментарии:

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

Ответ №2:

Стандартный подход, когда клиент подключается к серверу, заключается в отправке имени пользователя и пароля для идентификации клиента. Если вы хотите, чтобы это было прозрачно, вы можете использовать System.getProperty("user.name") , который прост, но не очень безопасен.

Комментарии:

1. Внутри компании имена пользователей будут уникальными. Если это интернет-приложение, пользователю придется ввести имя пользователя.

2. Спасибо за разъяснение. Я думал об «Интернете» и не учел, что все пользователи могут быть из одной организационной структуры.

Ответ №3:

Я просто приведу грубую суть и улучшу ее позже, но здесь идет:


Обзор:

Итак, вы сохраняете некоторые данные на сервере, а затем, когда клиент подключается, он отправляет имя пользователя и пароль и аутентифицируется на основе этих данных. Вы сохраняете конечную точку Socket на карте, которая является String username -> Socket socket . Также сохраните обратное, Socket socket -> String username . Используйте это, чтобы найти имя пользователя, когда вы получаете что-то из сокета. Даже если вы используете каналы сокетов, вы все равно можете получить сокет из канала, используя методы канала.


Для управления этими соединениями с помощью NIO:

О чем я не говорил, так это о том, как вы будете получать данные имени пользователя / пароля в первую очередь. Для этого я советую создать фрейминг. Прочитайте размер данных, а затем прочитайте тип данных, который должен быть двумя целыми числами. Вы можете записывать объекты непосредственно в поток сокета и обрабатывать их в том же порядке на другом конце.

Вы должны использовать селектор с ключами выбора и сохранять полученные данные в буферах, прикрепленных к этим ключам выбора. Затем вы просто продолжаете выбирать и добавлять полученные данные в буфер, если сокет доступен для чтения, пытаясь обработать буфер. Если в буфере есть полезные данные после записи в него из чтения (т. Е. вы получили размер данных, а также полную длину данных), вам нужно удалить данные и сжать буфер — т. Е. переместить позицию буфера вверх на размер длины данных (размер int) размер типа данных (размер int) длина данных, а затем уменьшить весь набор до 0 и установить позицию в конец текущих полученных данных. Используйте buffer.compact() для этого.

Я бы действительно посоветовал что-то вроде KryoNet для выполнения тяжелой работы. Сетевое программирование — сложная задача. Но это может быть для назначения, так что…