无法使用goprotobuf解码消息。

huangapple go评论90阅读模式
英文:

Can't decode messages using goprotobuf

问题

我有以下的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;
}

以及使用goprotobuf包编写的以下Go程序。该程序:

  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:

  • 名字:Fido
  • 品种:hound
  • 腿的数量:4
  • 牙齿数量:24

然而,在Go程序中进行解组总是返回错误信息"illegal tag 0"。

我怀疑我可能误解了解码的API,但是到目前为止,我还没有找到问题所在。

英文:

I have the following proto file:

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

And the following Go program written using the goprotobuf package. The program

  1. reads a Varint from stdin in order to get the length of the encoded message,
  2. reads that number of bytes from stdin into a buffer, and
  3. attempts to unmarshal the buffer into a Dog.

--START CODE--

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)

}

--END CODE--

And the this encoded message (preceded by a Varint) (in hexdump form)

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

which i can successfully decode using c++ and libprotobuf as a Dog with

  • name: Fido
  • breed: hound
  • nbLegs: 4
  • nbTeeth: 24

Unmarshaling in the go program, however, always returns the error "illegal tag 0".

I suspect that I've misunderstood the decoding API but, so far, I can't see how.

答案1

得分: 0

尝试直接解码字节,而不是创建缓冲区,像这样:

你还可以检查一下 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, "接收到长度为 %d 的 %s\n", sz, render(dog))
}
英文:

Try just umarshalling the bytes instead of creating a buffer like this:
You may also want to check to see if os.Stdin.Read(bytes) is actually reading 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)

}

huangapple
  • 本文由 发表于 2014年4月25日 08:46:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/23282321.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定