【问题标题】:Can't decode messages using goprotobuf无法使用 goprotobuf 解码消息
【发布时间】:2017-03-08 17:10:00
【问题描述】:

我有以下 proto 文件:

package dogs;

enum Breed {
    terrier = 0;
    shepherd = 1;
    hound = 2;
};

message Dog {
    required int64 nbLegs = 1;
    optional int64 nbTeeth = 2 [default=24];
    optional Breed breed = 3;
    optional string name = 4;
}

以下 Go 程序使用 goprotobuf 包编写。程序

  1. 从标准输入读取 Varint 以获取编码消息的长度,
  2. 从标准输入读取该字节数到缓冲区中,然后
  3. 尝试将缓冲区解组为 Dog。

--开始代码--

package main

import "bufio"
import "encoding/binary"
import "os"
import "log"
import "fmt"
import "dogs"
import "code.google.com/p/goprotobuf/proto"

func render(dog *dogs.Dog) string {
    return fmt.Sprintf("Dog: %v %v %v %v", dog.GetName(), dog.GetBreed(), dog.GetNbLegs(), dog.GetNbTeeth())
}

func main() {
    var dog = new(dogs.Dog)
    stdin := bufio.NewReader(os.Stdin)
    sz, _ := binary.ReadVarint(stdin)
    bytes := make([]byte, sz)
    os.Stdin.Read(bytes)
    buf := proto.NewBuffer(bytes)
    err := buf.Unmarshal(dog)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Fprintf(os.Stderr, "Receiving %s of length %d\n", render(dog), sz)

}

--结束代码--

还有这个编码的消息(前面有一个 Varint)(以 hexdump 形式)

0000000: 1408 0418 0222 0446 6964 6f              .....".Fido

我可以使用 c++ 和 libprotobuf 作为 Dog with 成功解码

  • 姓名:菲多
  • 品种:猎犬
  • nbLegs:4
  • nb 牙齿:24

然而,在 go 程序中解组,总是返回错误“illegal tag 0”。

我怀疑我误解了解码 API,但到目前为止,我还看不出是怎么回事。

【问题讨论】:

    标签: go protocol-buffers


    【解决方案1】:

    尝试仅对字节进行编组,而不是像这样创建缓冲区: 您可能还想检查 os.Stdin.Read(bytes) 是否真的在读取 sz。

    func main() {
        var dog = new(dogs.Dog)
        stdin := bufio.NewReader(os.Stdin)
        sz, _ := binary.ReadVarint(stdin)
        bytes := make([]byte, sz)
        stdin.Read(bytes)
        err := buf.Unmarshal(dog, bytes)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Fprintf(os.Stderr, "Receiving %s of length %d\n", render(dog), sz)
    
    }
    

    【讨论】:

    • 是的,我应该检查所有读取的输出。正如 Rob Pike 自己向我指出的那样,第一次读取是通过 bufio 完成的,它将整个 os.Stdin 排入缓冲区,然后直接来自 os.Stdin 的第二次读取没有要获取的输入。跨度>
    • 故事的寓意:忽略返回值几乎总是错误的做法。
    猜你喜欢
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 2018-03-02
    • 1970-01-01
    • 2019-02-13
    相关资源
    最近更新 更多