Java сокеты - как определить тип данных на стороне сервера? - PullRequest
1 голос
/ 07 мая 2010

Я использую сокеты Java для клиент-серверного приложения.У меня есть ситуация, когда иногда клиент должен отправить байтовый массив (используя byteArrayOutputStream), а иногда он должен отправить пользовательский объект Java.Как я могу прочитать информацию из входного потока на стороне сервера и определить, что находится в потоке, чтобы я мог правильно обработать это?

Ответы [ 8 ]

2 голосов
/ 07 мая 2010

Есть несколько способов справиться с этим.

Одним из них является Object Serialization, который отправляет его с помощью Java Object (In | Out) putStream. Вы сталкиваетесь с небольшой проблемой, когда знаете, когда читать объект из потока.

Еще один способ - маршалировать и демаршировать XML. Использует немного больше трафика, но его легче отлаживать и запускать. Для этого полезно иметь хорошо документированную XML-схему. Преимущество здесь в том, что вы можете использовать для этого существующие библиотеки XML.

Вы можете попробовать пользовательский формат, если хотите, но он, вероятно, окажется просто небрежной, менее многословной версией XML.

2 голосов
/ 07 мая 2010

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

Вы можете довольно легко использовать JAXB для сортировки данных в и из XML. А JAXB даже превратит объекты байтового массива в шестнадцатеричные строки или Base64 для вас.

2 голосов
/ 07 мая 2010

Обычно это делается путем отправки «заголовка» перед телом, содержащего информацию о теле. Посмотрите, например, HTTP протокол . HTTP-поток существует из заголовка, который отделен от тела двойной новой строкой. Заголовок, в свою очередь, состоит из нескольких полей в формате name: value, каждое из которых разделено одной новой строкой. В этом конкретном случае вы бы в HTTP использовали заголовок Content-Type для определения типа данных тела.

Поскольку Java и TCP / IP не предоставляют стандартных возможностей для этого, вам нужно будет подробно указать и задокументировать формат, который вы собираетесь отправлять по линии, чтобы другая сторона знала, как обрабатывать поток. Конечно, вы также можете получить стандартную спецификацию. Например. HTTP или FTP.

2 голосов
/ 07 мая 2010

В общем, я не верю, что есть функция, встроенная в Java, которая позволяет вам делать это.

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

Например, вы можете добавить к вашим сообщениям целое число, чтобы каждый раз, когда вы получаете сообщение, вы читали первые 4 байта (целое число составляло 4 байта) и интерпретировали его значение (например, 1 = байтовый массив, 2 = пользовательский объект Java, 3 = другой пользовательский объект Java, ...).

Вы можете также рассмотреть возможность добавления целого числа, содержащего размер сообщения, чтобы вы знали, когда заканчивается текущее сообщение и начинается следующее сообщение.

1 голос
/ 07 мая 2010

Сначала прочитайте данные в байтовый массив на сервере. Напишите свою собственную процедуру синтаксического анализа, чтобы ничего не делать, кроме как определить, что находится в байтовом массиве.

Во-вторых, выполните полный анализ объекта на основе идентификации с первого шага. Если для синтаксического анализа требуется передача входного потока, вы всегда можете поместить байтовый массив, прочитанный на первом этапе, в новый экземпляр ByteArrayInputStream.

1 голос
/ 07 мая 2010

Вам необходимо определить протокол, чтобы указать, какой тип данных следует. Например, вы можете начать каждую передачу со строки или перечисляемого значения. Сервер сначала прочтет это, а затем прочитает следующие данные, основываясь на значении заголовка.

0 голосов
/ 07 мая 2010

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

0 голосов
/ 07 мая 2010

Что бы вы могли сделать, это добавить к отправляемым вами данным целое число, используемое для определения типа.

Таким образом, вы можете прочитать первые 4 байта, а затем определить тип данных.

...