Невозможно демаршалировать байты с помощью protobuf

Я пишу простой клиент-сервер, чтобы познакомиться с protobuf.
У меня есть следующий файл message.proto:

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

И это код на стороне клиента (без ошибок):

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

и на стороне сервера:

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

Байты проходят через сокет нормально, но когда на стороне сервера я вызываю Unmarshal, я получаю следующую ошибку:

panic: в теге protobuf недостаточно полей в Text.state:

Что странно, если я вызываю Unmarshal на стороне клиента, он работает нормально.
Моя версия протокола - 3.11.2, и я установил ее

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

Я создал файл message.pb.go

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

Тогда может показаться, что проблема возникает из-за отправки байтов через сокет, но это срез с точно такими же значениями.

2 ответа

Если вы столкнулись с этой ошибкой и используете github.com/gogo/protobuf, вы можете столкнуться с известной проблемой в этой библиотеке, решение которой не ожидается в ближайшее время. Обходной путь - использовать другую прото-библиотеку, такую ​​как google.golang.org/protobuf/proto вместо.

Хорошо, я решил. Оказывается, метод ReadAll создал фрагмент с мусором в конце (я думаю), поэтому, когда я сделал

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

все заработало как положено!

Другие вопросы по тегам