2016-10-31 8 views
1

Я пытаюсь создать клиентский сервер UDP. Я уже мог читать сообщения, выполнив следующие действия:Java-объект для UDP-байта []

Моя входящее сообщение BIG_ENDIAN и структура такова:

UINT8 type;   
UINT8 flags;    
UINT16 len;     
UINT32 sequenceN;   
UINT16 startIdx;   
UINT16 endIdx; 

Соответствующие Java объекты:

short type; 
short flags; 
int len; 
long sequenceN; 
int startIdx; 
int endIdx; 

Для преобразования от UDP до Java Я использую следующее:

typeArray = Arrays.copyOfRange(msg, 0, 1); 
type = Util.reassembleShort(typeArray); 
flagsArray = Arrays.copyOfRange(msg, 1, 2); 
flags = Util.reassembleShort(flagsArray); 
lenArray = Arrays.copyOfRange(msg, 2, 4); 
len = Util.reassembleInt(lenArray); 
seqArray = Arrays.copyOfRange(msg, 4, 8); 
sequenceN = Util.reassembleLong(seqArray); 
startArray = Arrays.copyOfRange(msg, 8, 10); 
startIdx = Util.reassembleInt(startArray); 
endArray = Arrays.copyOfRange(msg, 10, 12); 
endIdx = Util.reassembleInt(endArray); 

Чтобы собрать байт части массива в объекты Java Я использую следующие (AKA звонки на Util.reassemble * выше):

Короткие

ByteBuffer buffer = ByteBuffer.wrap(input); 
buffer.order(ByteOrder.BIG_ENDIAN); 
short result = ((short) (buffer.get() & 0xff)); 

Long

ByteBuffer buffer = ByteBuffer.wrap(input); 
buffer.order(ByteOrder.BIG_ENDIAN); 
long result = ((long) buffer.getInt() & 0xffffffffL); 

Int

ByteBuffer buffer = ByteBuffer.wrap(input); 
buffer.order(ByteOrder.BIG_ENDIAN); 
int result = (buffer.getShort() & 0xffff); 

Строка

String result = new String(removeStringGarbage(input), Charset.forName("US-ASCII")); 

Это отлично работает. Мой вопрос ... как мне сделать обратное и получить объекты в правильно размерный байтовый буфер, чтобы отправить обратно на UDP?

+1

«Для преобразования из UDP в Java я использую следующие »- почему бы не просто прочитать« ByteBuffer »вместо этого? Дешевле и читабельнее. – chrylis

+0

Извините, забыли упомянуть переменную «msg» - это входящий байтовый буфер. – Tacitus86

+0

Байт-буфер или 'ByteBuffer'? В последнем случае вы можете просто 'getShort()' или что угодно. – chrylis

ответ

0

В случае, если вы должны точно следовать по существуному бинарному формату, попросите «Kaitai Struct» (http://kaitai.io/).

Если вы можете позволить себе изменить вам формат сериализации (т.е. вы контролируете его), обратите внимание на «Протокол Буферы»: https://developers.google.com/protocol-buffers/docs/javatutorial

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

И с «протокольными буферами» вы также получаете расширяемость, то есть вы можете развивать свой протокол, сохраняя при этом обратную совместимость.

Если вы все еще хотите сериализации/десериализации данных вручную, просто использоватьputX методы в ByteBuffer в следующем виде:

buffer.put((byte)(type & 0xFF)); 
buffer.put((byte)(flags & 0xFF)); 
buffer.putShort((short)(len & 0xFFFF)); 
buffer.putInt((int)(sequenceN & 0xFFFFFFFF)); 
buffer.putShort((short)(startIdx & 0xFFFF)); 
buffer.putShort((short)(endIdx & 0xFFFF)); 

Пут тип операции должна соответствовать вашему двоичную размер поля (т.е. положить () для UINT8, putShort для UINT16, putInt для UINT32 ...), и вы должны применить к нему подходящую маску (например, 0xFF для краткости, 0xFFFF для int и т. д.)

+1

Он * * точно соответствует существующему проводному протоколу. Он указан в вопросе. – EJP

+0

Возможно, вы, вероятно, правы в этом (меня сначала смутил «клиентский сервер» и подразумевал, что OP контролирует проводную кодировку). Я изменил свой ответ соответственно. – zeppelin

+0

Спасибо zeppelin. Просто нужно выяснить, как конвертировать (размер вниз). Мне пришлось увеличить размер, исходящий от uint * до java-объекта. Так что теперь мне нужно пойти Short -> uint8, Int -> uint16, long -> uint32. Есть идеи? – Tacitus86

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

  • Нет связанных вопросов^_^