4

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.

jasiekc
  • 63
  • 1
  • 6

2 Answers2

4

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.

StockB
  • 755
  • 1
  • 13
  • 33
2

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!

jasiekc
  • 63
  • 1
  • 6
  • 2
    it is not some junk, it is the data already existing within it. After read op you should always make use of the returned number of bytes read to appropriately handle the data. –  Nov 17 '20 at 18:06
  • Yeah I will definitely remember that :) The reason why I didn't use it is that after deeper inspection the slice itself had correct length, but it had some large capacity (so in theory it ended right where it should), that's why I didn't put the [:n] in the first place – jasiekc Nov 18 '20 at 10:41