Как читать, чтобы inputtream в связи сокета TCP для нескольких форматов в Java - PullRequest
0 голосов
/ 22 апреля 2009

В связи на основе TCP мне нужно прослушивать / читать несколько форматов в DataInputStream. Такие как запись и запись UTF.

Мне нужно определить режим, используемый другим концом для переключения в этот режим, например, когда используется writeUTF (String), мне нужно использовать readUTF (), а если используется запись (byte []), тогда я должен возможность переключиться на чтение (), чтобы получить данные.

Я пытался использовать markSupported, mark, reset, но не смог его реализовать. Я намерен понюхать несколько первых байтов, чтобы понять формат, а затем передать его в нужный формат.

Пожалуйста, укажите также, могу ли я использовать любой другой поток ввода / вывода для связи по протоколу TCP.

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

Ответы [ 4 ]

1 голос
/ 22 апреля 2009

Я не совсем уверен, чего вы действительно пытаетесь достичь здесь. Вы не можете определить, какой метод использует удаленный конец, так как все разрешит отправку потока байтов.

Итак, на вашем конце вы получите поток байтов, а затем вы должны определить, что это будет представлять. Какой набор форматов вы хотите определить? Вы можете перечислить это? Можете ли вы контролировать, как удаленный конец отправляет их? Если это так, я бы реализовал некоторую форму заголовка, например, чтобы (скажем) первый байт идентифицировал тип (например, строка, массив чисел и т. Д.), А затем ваш клиент мог переключать режимы соответствующим образом.

Если вы можете использовать сериализацию объектов Java и соответствующие потоки объектов, тогда вы можете разрешить объект Java, а затем использовать instanceof, например.

ObjectInputStream ois = new ObjectInputStream(is);
Object obj = ois.readObject();

if (obj instanceof String) {
   // do string-related stuff
}

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

0 голосов
/ 17 мая 2009

Проблема, с которой вы столкнетесь, заключается в том, что все, что вы можете написать UTF (), вы также можете сделать с помощью write () и наоборот. Это никоим образом не означает разницу, не делая предположений о типе данных, которые могут быть отправлены. Это может быть сделано для некоторых конкретных случаев, но не будет работать в общем случае.

Читатель не может точно определить длину записи (в байтах []). Возможно, вы обнаружите, что read () большую часть времени будет читать ту же самую длину по шлейфу, но не будет работать в реальной сети.

Таким образом, отправитель выполняет запись (byte []), за которой следует writeUTF (String). Нет способа узнать, как долго длилась первая запись, поэтому нет способа определить, когда начинается writeUTF (опять же, если вы не сделаете предположений относительно типа отправляемых данных)

Решением вашей проблемы является отправка длины фрагмента данных с последующим типом данных. например,

запись (байты) заменяется writeInt (bytes.length), запись ((байт) 1 / * байт * /), запись (байты)

writeUTF (байты) заменяется на byte [] bytes = text.getBytes ("UTF-8"); writeInt (bytes.length), write ((byte) 2 / * UTF * /), write (bytes)

Таким образом, получатель знает длину сообщения и его тип.

0 голосов
/ 22 апреля 2009

Вместо DataInputStream вы можете использовать ObjectOutputStream для записи и ObjectInputStream для чтения.

Вы можете написать так:

    ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
    objectOutputStream.writeObject("xyz");

И читать так:

    ObjectInputStream objectInputStream = new ObjectInputStream(in);
    Object obj = objectInputStream.readObject();
0 голосов
/ 22 апреля 2009

Я бы посоветовал взглянуть на apache mina framework для сетевого взаимодействия. Большинство (если не все) низкоуровневые сетевые функции обрабатываются для вас из mina.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...