Стандарт связи между сервером и клиентом - PullRequest
0 голосов
/ 30 января 2020

У меня есть вопросы относительно того, как сервер и клиент определяют стандарт связи между ними. Для справки я использую Java и код здесь .

  1. Клиенту необходим IP-адрес сервера для подключения к нему. Если сервер использует метод InetAddress.getLocalHost().getHostAddress(), IP-адрес, который будет возвращен, будет локальным: полезно, если клиент находится на том же компьютере, что и сервер, в противном случае - меньше. Как я могу получить IP сервера, который нужен клиенту? Можно ли получить эту информацию, не используя внешние службы или сайты, которые проверяют ваш сервер и возвращают ваш publi c IP?
  2. Предположим, я, клиент, установил Socket связь с сервером. Теперь мне нужно открыть поток ввода и вывода, который должен быть совместим с потоком на стороне сервера. Как я могу знать заранее правильный вид? Для примера, давайте рассмотрим случай time.nist.gov , порт 13. Я ожидаю, что вывод сообщения на этот сервер будет String, инкапсулируя текущую дату. Сервер передает String через ObjectOutputStream или, может быть, OutputStreamWriter? Как я могу знать?

1 Ответ

2 голосов
/ 30 января 2020

Клиенту необходим IP-адрес сервера для подключения к нему ... Как я могу получить IP-адрес сервера, который нужен клиенту? Можно ли получить эту информацию, не используя внешние службы или сайты, которые проверяют ваш сервер и возвращают ваш publi c IP?

Клиент должен знать либо IP-адрес, либо имя хоста сервер. Если имя хоста известно, IP-адрес можно определить на стороне клиента , используя InetAddress.getByName( "java.sun.com" ), используя java .sun.com в качестве примера.

Мне нужно открыть поток ввода и вывода, который должен быть совместим с потоком на стороне сервера. Как я могу заранее знать правильный тип?

Поскольку обмен сообщениями варьируется от протокола к протоколу, клиент должен знать, что поддерживает сервер, и соответствующим образом записывать свои входные и выходные потоки. Обычно клиент-серверные системы обмениваются данными на основе байтов. То есть данные простого байта будут обмениваться между клиентом и сервером. Затем они преобразуют эти байты из / в символы , где это необходимо на основе согласованной кодировки символов, например UTF-8.

Передает ли сервер указанную строку через ObjectOutputStream или может быть OutputStreamWriter?

Вот где идея протокола нуждается в понимании. Возможно, вы уже знаете, однако, я пишу это просто, чтобы объяснить четко. Протокол - это соглашение или контракт стиля обмена сообщениями - сколько байтов отправлять, когда отправлять, как кодировать и т. Д. c. Например, в SMTP клиент должен сначала сказать HELO или EHLO, после получения которого сервер возвращает указанный c ответ. Клиент должен знать, чего ожидать на этом этапе и как двигаться дальше на основе протокола.

Использование ObjectInputStream и ObjectOutputStream

Теперь ObjectInputStream и ObjectOutputStream - это Java -специфическая c обертка над потоками ввода-вывода для чтения и записи байтовых буферов в "форме" объектов Java. То есть эти классы служат только для целей Java -object-Speci c. Это нормально, если известно, что сервер взаимодействует с использованием сериализованных / десериализованных Java объектов. Однако сервер, к которому подключается клиент, может вообще не использовать Java! Или даже если это так, он может общаться в чистых символах или байтах, а не в Java объектах.

Я не уверен, какой протокол time.nist.gov:13 использует. Вам нужно будет это понять и соответствующим образом кодировать своего клиента. Однако, поскольку вы упомянули, что он возвращает строку:

  1. Просто используйте socket.getInputStream() на клиенте, не заключая его в ObjectInputStream
  2. Считайте байты из этого потока до EOF
  3. Преобразовать эти байты в String с учетом кодировки символов, опубликованной сайтом, скажем, UTF-8. new String( bytes, StandardCharsets.UTF_8 ).
...