Java: Как создать пакет с байтами? - PullRequest
3 голосов
/ 06 июня 2011

Я работаю в проекте, где мне нужно прочитать некоторые значения и отправить через сокетное соединение.Это формат пакета, который я должен создать: enter image description here

я должен прочитать эти значения (я не знаю, какой тип короля это должно быть каждое значение, int или строка и т. Д.): Type:тип операции (как получить только 4 бита?) reserverd: я буду заполнять источником 0: кто отправляет получатель сообщения: кто должен получать алгоритм сообщения: какой алгоритм goona будет использоваться для шифрования заполнения сообщения: используйте егов режиме алгоритма шифрования: в каком режиме шифровать

я должен прочитать эти значения и создать этот пакет, который должен иметь только 7 байтов.

как я могу это сделать?это должно быть что-то вроде этого, я думаю:

byte[] r = new byte[]{
               type+reserverd, 
               origin_1_byte, origin_2_byte, 
               receiver_1_byte, receiver_2_byte, 
               algorithm+padding, 
               mode};

ОБНОВЛЕНИЕ:

ByteBuffer buffer = ByteBuffer.allocate(100);
// read data into buffer
buffer.rewind();
buffer.order(ByteOrder.LITTLE_ENDIAN);
// 0xf and co mask off sign extension -> handle byte as unsigned
int type = (buffer.get() >> 4) & 0xf; // 15 in decimal

buffer.rewind();
buffer.put((byte)(type << 4));
System.out.println("type = " + type);


output : 0 (why ?)

Есть идеи?

Ответы [ 5 ]

2 голосов
/ 06 июня 2011

Просто используйте ByteBuffer и пакет nio.Таким образом, вы можете легко читать данные из сети, и вам не нужно беспокоиться об Endianess (это важно! Если вы используете потоки, вам, скорее всего, придется реализовать сдвиг самостоятельно - хотя это может быть хорошим упражнением).Не забудьте установить порядковый номер буфера на правильное значение.Мы используем int для внутреннего использования, потому что a) все математические операции в любом случае возвращают ints и b) вы можете обрабатывать значения как беззнаковые.

    ByteBuffer buffer = ByteBuffer.allocate(100);
    // read data into buffer
    buffer.rewind();
    buffer.order(ByteOrder.LITTLE_ENDIAN);
            // 0xf and co mask off sign extension -> handle byte as unsigned
    int type = (buffer.get() >> 4) & 0xf; 
    int origin = buffer.getShort() & 0xffff;
    int receiver = buffer.getShort() & 0xffff;
    // and so on

, чтобы записать данные обратно, вы в значительной степени делаете обратное:

    ByteBuffer buffer = ByteBuffer.allocate(100);
    buffer.rewind();
    buffer.put((byte)(type << 4));
    buffer.putShort((short)origin);
    // and so on

Редактировать: Обычно вы считываете данные непосредственно в ByteBuffer из сетевого канала и используете пакет Java NIO.Краткое руководство: здесь .Но так как у вас уже есть Socket, мы сделаем это немного проще.Обратите внимание, что я проигнорировал всю проверку ошибок для краткости.Использование OutputStream и WritableByteChannel (с записью) работает в другом направлении.

InputStream is = socket.getInputStream();
ReadableByteChannel source = Channels.newChannel(istream);
ByteBuffer buffer = ByteBuffer.allocateDirect(headerSize);
source.read(buffer);
// now header is in buffer and can be used as seen above. 
0 голосов
/ 06 июня 2011

ByteBuffer, как предлагается в других ответах, или DataOutputStream.

0 голосов
/ 06 июня 2011

вы бы использовали битовые сдвиги (используя <<) и битовые ор или (используя |)

new byte[]{
           type<<4|reserverd, 
           origin_1_byte, origin_2_byte, 
           receiver_1_byte, receiver_2_byte, 
           algorithm<<4 | padding, 
           mode};

для их извлечения вам понадобятся маски и смены (buff[0]&0xf0)>>>4 извлечет тип, например)

0 голосов
/ 06 июня 2011

У меня была такая же проблема с использованием байтов, также я обнаружил, что в Java нет "беззнаковых байтов", поэтому значения байтов будут только от -128 до 127, если я прав. Я был вынужден использовать шорты, как если бы они были байтами, поэтому я мог использовать значения до 255.

Я уверен, что есть выход, но в то время у меня просто не было достаточно времени, чтобы выяснить это

0 голосов
/ 06 июня 2011

Посмотрите на ByteBuffer.

Также посмотрите на битовые операции, такие как «сдвиг».Если вам нужно сохранить 3 в type и 7 в reserved, то вам просто нужно сохранить их в 8-битном byte смещением.

byte typeReserved = (3 << 4) | 7;

Хотите получить значение из?

byte type = (typeReserved >> 4) & 0xF;
byte reserved = typeReserved & 0xF;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...