2017-11-05 5 views
1

私はINT32を別のアプリケーションに送る必要があるが、私が読んだところでは、messagepack.putIntmessagepack.putLongはこれを問題の原因となるUINT32に最適化しようとしている受信アプリケーション。Javaを使用してMessagePackにINT32をパックするにはどうすればよいですか?

受信アプリケーションは私にエラーメッセージ

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> 

誰かがこの同じ問題を持っていたし、それに対する解決策を述べ

は以下の通りでした

"問題を発見したので、metricTankのように、メッセージオブジェクトのtimeプロパティがIN T32では、packInt(またはpackLong)は常にmetricTankのようなUINT32に最適化しようとします。 addPayloadを使用してMessagePacker.Code.INT32をシリアライズしてから、timeプロパティの実際の4バイトを覚えなければなりませんでした。

しかし、私は何をすべきかわからないと私はOPに連絡することができません。

私は次のことを試してみましたが、それはバイト配列を5にする必要がある

ByteBuffer buf = ByteBuffer.allocate(1 + Long.BYTES); 
buf.put(MessagePack.Code.INT32); 
buf.putLong(md.time); 
packer.addPayload(buf.array()); 

を動作しません。長さは、最初のバイトは、ヘッダである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()); 

Thをする必要がエラーは発生しませんが、受信した時刻値は正しくありません。

INT32をUINT32ではなく、私のMessagePackにパックする方法や、正しい方法でデータをパックして受信側のアプリケーションで正しくアンパックする方法を教えてください。


受信側アプリケーションは、Goに書き込まれたデータ

// 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 
    } 
} 

を復号するtinylib msgpライブラリを使用しているこれは、最初のバイトをチェックし、最初のバイトがあるmint32に等しい場合0xd2の場合、次の4バイトが読み込まれます。これはlongの値を使用します。getmint32

func getMint32(b []byte) int32 { 
    return (int32(b[1]) << 24) | (int32(b[2]) << 16) | (int32(b[3]) << 8) | (int32(b[4])) 
} 

答えて

0

この特定の問題では、受信側のアプリケーションでINT32を受信し、バイト配列の長さを5にする必要がありました。最初のバイトは、OPで見られる0xd2というヘッダーです。これは、それがINT32であることをデコード方法に伝えます。次の4つの4バイトは時間値です。

私は、long型が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) 
関連する問題