英文:
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程序。该程序:
- 从标准输入读取一个Varint,以获取编码消息的长度,
- 从标准输入读取相应数量的字节到缓冲区中,
- 尝试将缓冲区解码为一个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
- reads a Varint from stdin in order to get the length of the encoded message,
- reads that number of bytes from stdin into a buffer, and
- 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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论