Can't unmarshal bytes using protobuf

Viewed 3075

I am writing a simple client-server to get to know protobuf.
I have the following message.proto file:

syntax = "proto3"; 
package main;
message Text {
    string name = 1;
    int32 id = 2;
}

And this is the code on the client side (ommited errors):

mssg := &Text{Name: "John Doe", Id: 4721}
bytes, _ := proto.Marshal(mssg)
conn, _ := net.Dial(...)
conn.Write(bytes)

and on the server side:

...
message, _ := ioutil.ReadAll(conn)
mssg := Text{}
err = proto.Unmarshal(message, &mssg)

The bytes go through the socket just fine, but when on the server side I call the Unmarshal I get the following error:

panic: protobuf tag not enough fields in Text.state:

What is weird is that if I call the Unmarshal on the client side it works just fine.
My protoc version is 3.11.2 and I installed it by

go get google.golang.org/protobuf/cmd/protoc-gen-go
go install google.golang.org/protobuf/cmd/protoc-gen-go

I created the message.pb.go file by

protoc.exe -I="." --go_out="." message.proto

It would seem, then, that the problem arises because of sending the bytes through the socket, but it's a slice with the exact same values.

2 Answers

If you encounter this error and are using github.com/gogo/protobuf, you may be encountering a known issue in this library that isn't expected to be solved anytime soon. The workaround is to use another proto library such as google.golang.org/protobuf/proto instead.

Ok, I solved it. Turns out the ReadAll method created a slice that had some junk at the end (I think) so when I did

n, err := conn.Read(buffer)
proto.Unmarshal(buffer[:n], &mssg)

it worked as expected!

Related