我遇到了需要将INT32发送到其他应用程序的问题,但是从我读过的内容来看, messagepack.putInt 和 messagepack.putLong < / em>将尝试将此优化为UINT32,这会导致接收应用程序出现问题。
接收应用程序正在向我提供错误消息
decode error, skipping message. msgp: attempted to decode type "uint" with method for "int"
我正在使用具有依赖性的maven
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack-core</artifactId>
<version>0.8.13</version>
</dependency>
其他人有同样的问题,并说明解决方案如下
&#34; 好的,所以我们发现了问题,似乎metricTank要求将消息对象的time属性序列化为INT32,但是packInt(或packLong)总是会尝试将其优化为Uint32是metricTank不喜欢的。所以我们不得不使用addPayload和序列化MessagePacker.Code.INT32,然后使用time属性的实际4个字节。&#34;
但我不确定该怎么办,我无法联系OP。
我尝试过以下但是不起作用
ByteBuffer buf = ByteBuffer.allocate(1 + Long.BYTES);
buf.put(MessagePack.Code.INT32);
buf.putLong(md.time);
packer.addPayload(buf.array());
字节数组的长度必须为5,第一个字节是标头, 0xd2 ,其他4个字节需要为值
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeLong(md.time);
dos.close();
byte[] longBytes = baos.toByteArray();
ByteBuffer lBytes = ByteBuffer.allocate(4);
for (int i = 0; i < 4; i++) {
lBytes.put(longBytes[i]);
}
ByteBuffer buf = ByteBuffer.allocate(5);
buf.put((byte) 0xd2);
buf.put(lBytes.array());
这不会产生错误,但收到时时间值不正确。
有人可以告诉我如何将INT32打包到我的MessagePack而不是UINT32,或者告诉我如何以正确的方式打包数据,以便在接收应用程序中正确解压缩?
接收应用程序是用Go编写的,并使用tinylib msgp库来解码数据
// ReadInt64Bytes tries to read an int64
// from 'b' and return the value and the remaining bytes.
// Possible errors:
// - ErrShortBytes (too few bytes)
// - TypeError (not a int)
func ReadInt64Bytes(b []byte) (i int64, o []byte, err error) {
l := len(b)
if l < 1 {
return 0, nil, ErrShortBytes
}
lead := b[0]
if isfixint(lead) {
i = int64(rfixint(lead))
o = b[1:]
return
}
if isnfixint(lead) {
i = int64(rnfixint(lead))
o = b[1:]
return
}
switch lead {
case mint8:
if l < 2 {
err = ErrShortBytes
return
}
i = int64(getMint8(b))
o = b[2:]
return
case mint16:
if l < 3 {
err = ErrShortBytes
return
}
i = int64(getMint16(b))
o = b[3:]
return
case mint32:
if l < 5 {
err = ErrShortBytes
return
}
i = int64(getMint32(b))
o = b[5:]
return
case mint64:
if l < 9 {
err = ErrShortBytes
return
}
i = getMint64(b)
o = b[9:]
return
default:
err = badPrefix(IntType, lead)
return
}
}
这将检查第一个字节,如果第一个字节等于 mint32 ,即 0xd2 ,则读取接下来的四个字节,这是长期使用 getmint32
func getMint32(b []byte) int32 {
return (int32(b[1]) << 24) | (int32(b[2]) << 16) | (int32(b[3]) << 8) | (int32(b[4]))
}
答案 0 :(得分:0)
在此特定问题中,接收应用程序必须接收INT32,并且bytes数组的长度必须为5。第一个字节是标题 0xd2 ,如OP中所示。这告诉解码方法它是INT32。接下来的四个4字节是时间值。
我忘了长8个字节,所以我们只需要使用一个整数的纪元时间。
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt((int)(md.time/1000));
dos.close();
byte[] timeBytes = baos.toByteArray();
ByteBuffer buf = ByteBuffer.allocate(5);
buf.put((byte) 0xd2);//header
buf.put(timeBytes);//time value (int32 bytes not uint32)