Java 对象到 UDP 字节[]
Java object to UDP byte[]
我正在尝试创建 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 个对象,我使用了以下内容(也就是上面对 Util.reassemble* 的调用):
短
ByteBuffer buffer = ByteBuffer.wrap(input);
buffer.order(ByteOrder.BIG_ENDIAN);
short result = ((short) (buffer.get() & 0xff));
长
ByteBuffer buffer = ByteBuffer.wrap(input);
buffer.order(ByteOrder.BIG_ENDIAN);
long result = ((long) buffer.getInt() & 0xffffffffL);
整数
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 发回?
如果您必须精确地遵循预先存在的在线二进制格式,请尝试 "Kaitai Struct" (http://kaitai.io/)。
如果您有能力更改序列化格式(即您可以控制它),请查看 "Protocol Buffers":https://developers.google.com/protocol-buffers/docs/javatutorial
在这两种情况下,使用预先存在的库以声明方式描述二进制协议,将为您节省大量时间和精力,
并且通常会产生更健壮的代码(因为代码生成器可以更好地处理损坏的数据并且永远不会出现拼写错误)。
并且 "Protocol Buffers" 您还可以获得可扩展性,即您可以在保持向后兼容性的同时改进您的协议。
如果您仍想 serialize/deserialize 手动处理您的数据,
只需使用 ByteBuffer 的 putX 方法如下:
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));
Put 操作类型应匹配您的二进制字段大小(即 UINT8 的 put()、UINT16 的 putShort、UINT32 的 putInt...),并且您必须为其应用适当的掩码(即 0xFF 简称 0xFFFF对于 int e.t.c.)
我正在尝试创建 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 个对象,我使用了以下内容(也就是上面对 Util.reassemble* 的调用):
短
ByteBuffer buffer = ByteBuffer.wrap(input);
buffer.order(ByteOrder.BIG_ENDIAN);
short result = ((short) (buffer.get() & 0xff));
长
ByteBuffer buffer = ByteBuffer.wrap(input);
buffer.order(ByteOrder.BIG_ENDIAN);
long result = ((long) buffer.getInt() & 0xffffffffL);
整数
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 发回?
如果您必须精确地遵循预先存在的在线二进制格式,请尝试 "Kaitai Struct" (http://kaitai.io/)。
如果您有能力更改序列化格式(即您可以控制它),请查看 "Protocol Buffers":https://developers.google.com/protocol-buffers/docs/javatutorial
在这两种情况下,使用预先存在的库以声明方式描述二进制协议,将为您节省大量时间和精力, 并且通常会产生更健壮的代码(因为代码生成器可以更好地处理损坏的数据并且永远不会出现拼写错误)。
并且 "Protocol Buffers" 您还可以获得可扩展性,即您可以在保持向后兼容性的同时改进您的协议。
如果您仍想 serialize/deserialize 手动处理您的数据, 只需使用 ByteBuffer 的 putX 方法如下:
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));
Put 操作类型应匹配您的二进制字段大小(即 UINT8 的 put()、UINT16 的 putShort、UINT32 的 putInt...),并且您必须为其应用适当的掩码(即 0xFF 简称 0xFFFF对于 int e.t.c.)