Невозможно демаршалировать байты с помощью 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)
все заработало как положено!