Java для связи с сокетом C ++, DataInputStream и eof, двоичный код, шифрование - PullRequest
0 голосов
/ 27 февраля 2010

Я пытаюсь, чтобы Java-сервер и клиенты C ++ общались по TCP при следующих условиях: текстовый режим и двоичный / зашифрованный режим. Моя проблема связана с индикатором eof для конца потока, который чтение DataInputStream (byte []) использует для возврата с -1. Если я отправляю двоичные данные, что должно предотвратить случайную последовательность байтов, представляющую eof и ложно указывающую read (), что поток заканчивается? Кажется, я ограничен текстовым режимом. Я могу жить с этим до тех пор, пока мне не понадобится масштабирование, но тогда у меня проблема в том, что я собираюсь зашифровать текст и добавить аутентификацию сообщения. Даже если бы я отправлял из другой Java-программы, а не из C ++, шифрование строки с помощью AES + MAC привело бы к двоичному выводу, а не к обычной строке. Что помешает какой-то зашифрованной последовательности, содержащей часть, идентичную eof? Итак, какие здесь решения?

Ответы [ 5 ]

2 голосов
/ 27 февраля 2010

Если я отправляю двоичные данные, что предотвращает случайную последовательность байтов, которая представляет eof и ложно указывает read (), что поток заканчивается?

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

Поскольку нет представления данных для (логического) EOF, вам не нужно беспокоиться о получении ложных EOF. Короче говоря, здесь нет проблемы, которую нужно решить.

0 голосов
/ 27 февраля 2010

Моя проблема связана с индикатором eof для конца потока, который читает DataInputStream (byte []) для возврата с -1.

Нет, это не так. Эта проблема мнимая. -1 - это код возврата InputStream.read (), который указывает, что узел закрыл соединение. Он не имеет ничего общего с данными, передаваемыми по соединению.

0 голосов
/ 27 февраля 2010

Как ответил Томас Порнин Aelx Martelli, DataInputStream используется даже для данных, не отправленных DataOutputStream или Java. Мой вопрос заключается в том, что, как говорится в документации, DataInputStream возвращает read (), когда заканчивается поток, то есть существует ли некоторая последовательность байтов, которую read () интерпретирует как конец потока, и что я не могу использовать ее, если есть ли вероятность того, что это произойдет в данных, которые я отправляю, например, если я отправлю общие двоичные данные?

0 голосов
/ 27 февраля 2010

Обычно при использовании потоков tcp у вас есть формат заголовка данных, который как минимум имеет поле, которое содержит ожидаемую длину данных, чтобы получатель точно знал, сколько байтов ожидать. Простой пример - формат TLV.

0 голосов
/ 27 февраля 2010

«конец потока» в TCP обычно сигнализируется закрытием сокета - , что - это то, что делает поток на самом деле заканчивается. Если вы не хотите, чтобы поток end , а просто сигнализировал об окончании «пакета» (за которым, вполне возможно, следуют другие пакеты в том же соединении), вы можете запустить каждый пакет с незашифрованным индикатором длины (скажем, 2 или 4 байта в зависимости от ваших потребностей). DataInputStream , в соответствии с его документами, подходит только для приема потоков, отправленных DataOutputStream , который, по-видимому, не имеет ничего общего с вашим вариантом использования, как вы его описали.

...