2014-09-29 1 views
0

В моем приложении клиенты отправляет файл на сервер в этом формате,Как проверить Integer полученные из потока сокета в Java

4 bytes of file length + actual file content 

Так сервер читает первые 4 байта, чтобы получить длину сообщения и то он читает до этой длины сообщения.

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

ByteArrayOutputStream lengthBuf = new ByteArrayOutputStream(4); 
byte[] output = new byte[4]; 

//Reading first 4 bytes from InputStream 
int readLength = inputStream.read(output); 
lengthBuf.write(outpu, 0, readLength); 

//Converting to integer 
int length = ByteBuffer.wrap(lengthBuf.toByteArray()).getInt(); 

Он отлично работает для действительных случаев. Но в случае, если клиент не может добавить длину в первые 4 байта, тогда эта длина получила некоторое нежелательное значение (1481988969). Как проверить, что первые 4 байта данных являются действительным целым числом?

+0

У вас проверено output.getInt(); извлекает первые четыре? – danielad

+1

Что делать, если inputStream.read() читает меньше 4 байтов? Что произойдет, если утверждение неверно? –

+0

BTW 'Integer'! =' Int' –

ответ

0

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

if(length==null) { 

    size = 4 ; 

} 
ByteArrayOutputStream lengthBuf = new ByteArrayOutputStream(size); 

int length = ByteBuffer.wrap(lengthBuf.toByteArray()).getInt(); 
+0

Извините, я не понимаю, что вы имеете в виду здесь. – Prabu

1

Я хотел бы сделать это таким образом.

DataInputStream dis = new DataInputStream(inputStream); 
int len = dis.readInt(); // read exactly 4 bytes 
byte[] bytes = new byte[len]; 
dis.readFully(bytes); 

Когда вы впервые прочитали, вы можете получить менее 4 байт. Когда вы читаете фактические данные, вам, возможно, придется много раз читать, чтобы получить все. read(byte[]) может вернуться, как только он получит 1 или более байт.

+0

Как вы говорите, что во время первого чтения я получаю меньше 4 байтов (я имею в виду readInt())? Я попытался использовать DataInputStream.readInt() в моем случае. Он возвращает случайное значение нежелательной почты. – Prabu

+0

@Prabu Я говорю, что вы можете читать меньше 4. Является ли значение 4 байта 'int' отправлено в маленьком или большом формате. DataInputStream предполагает большой конечный или сетевой формат, но в большинстве программ C/C++ по умолчанию используется немного endian. (Фактически это изменяется в зависимости от того, на котором он запущен) –

+0

Клиент отправляет 32-битный длинный конец (или сетевой порядок) и записывается в perl с использованием пакета («N a *», len, buf); – Prabu

2

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

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

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

if (integer < MAX_FILE_SIZE and integer > 0) valid(); 
// or integer >= 0 if empty files are allowed. 
else invalid(); 
+0

Это то, что я намеревался сделать, наконец, сравнением с некоторым максимальным значением. Я не могу изменить клиентский код, чтобы добавить дополнительный байт. – Prabu

+0

Тогда я не вижу другого шанса проверить правильность полученного значения. Возможно, вы можете отправить запрос дважды и проверить, дают ли оба результата одно и то же значение. –

Смежные вопросы