英文:
Bug in golang google protocol buffer
问题
我有一个Python程序和一个Golang程序,都从一个socket获取数据。我打印出它们接收到的字节。
Python代码:
Data = 0a300a084a6f686e20446f6510071a126a6f686e2e646f6540676d61696c2e636f6d220e0a0c3131312d3131312d31313130
Golang代码:
2016/04/02 23:21:08 50 bytes read from 192.168.0.1:65120
2016/04/02 23:21:08 00000000 0a 30 0a 08 4a 6f 68 6e 20 44 6f 65 10 08 1a 12 |.0..John Doe....|
00000010 6a 6f 68 6e 2e 64 6f 65 40 67 6d 61 69 6c 2e 63 |john.doe@gmail.c|
00000020 6f 6d 22 0e 0a 0c 31 31 31 2d 31 31 31 2d 31 31 |om"...111-111-11|
00000030 31 30 |10|
.proto文件在两者中是相同的。
syntax = "proto3";
package MC_Feed;
message Person {
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
string name = 1;
int32 id = 2; // Unique ID number for this person.
string email = 3;
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person people = 1;
}
在Python(以及C#)中,它可以正常工作。但在Golang方面,我得到了以下错误:
2016/04/02 23:21:08 proto: MC_Feed.AddressBook: illegal tag 0 (wire type 0)
这段Golang代码是我从网络上找到并稍作修改:
package main
import (
"github.com/golang/protobuf/proto"
"encoding/hex"
"./Simple"
"log"
"net"
)
const (
srvAddr = "239.0.0.222:345"
maxDatagramSize = 8192
)
func main() {
serveMulticastUDP(srvAddr, msgHandler)
}
func msgHandler(src *net.UDPAddr, n int, b []byte) {
log.Println(n, "bytes read from", src)
log.Println(hex.Dump(b[:n]))
newTest := &MC_Feed.AddressBook{}
err := proto.Unmarshal(b, newTest)
log.Println(err)
}
func serveMulticastUDP(a string, h func(*net.UDPAddr, int, []byte)) {
addr, err := net.ResolveUDPAddr("udp", a)
if err != nil {
log.Fatal(err)
}
l, err := net.ListenMulticastUDP("udp", nil, addr)
l.SetReadBuffer(maxDatagramSize)
for {
b := make([]byte, maxDatagramSize)
n, src, err := l.ReadFromUDP(b)
if err != nil {
log.Fatal("ReadFromUDP failed:", err)
}
h(src, n, b)
}
}
英文:
I have a python program and a golang program both getting data from a socket. I print the bytes it receives from both.
python
Data = 0a300a084a6f686e20446f6510071a126a6f686e2e646f6540676d61696c2e636f6d220e0a0c3131312d3131312d31313130
golang
2016/04/02 23:21:08 50 bytes read from 192.168.0.1:65120
2016/04/02 23:21:08 00000000 0a 30 0a 08 4a 6f 68 6e 20 44 6f 65 10 08 1a 12 |.0..John Doe....|
00000010 6a 6f 68 6e 2e 64 6f 65 40 67 6d 61 69 6c 2e 63 |john.doe@gmail.c|
00000020 6f 6d 22 0e 0a 0c 31 31 31 2d 31 31 31 2d 31 31 |om"...111-111-11|
00000030 31 30 |10|
The .proto file is identical in both.
syntax = "proto3";
package MC_Feed;
message Person {
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
string name = 1;
int32 id = 2; // Unique ID number for this person.
string email = 3;
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person people = 1;
}
On the python (and C# for that matter) it works fine. On the golang side, I get this error:
2016/04/02 23:21:08 proto: MC_Feed.AddressBook: illegal tag 0 (wire type 0)
The go code is something I got from the net and modified a little:
package main
import (
"github.com/golang/protobuf/proto"
"encoding/hex"
"./Simple"
"log"
"net"
)
const (
srvAddr = "239.0.0.222:345"
maxDatagramSize = 8192
)
func main() {
serveMulticastUDP(srvAddr, msgHandler)
}
func msgHandler(src *net.UDPAddr, n int, b []byte) {
log.Println(n, "bytes read from", src)
log.Println(hex.Dump(b[:n]))
newTest := &MC_Feed.AddressBook{}
err := proto.Unmarshal(b, newTest)
log.Println(err)
}
func serveMulticastUDP(a string, h func(*net.UDPAddr, int, []byte)) {
addr, err := net.ResolveUDPAddr("udp", a)
if err != nil {
log.Fatal(err)
}
l, err := net.ListenMulticastUDP("udp", nil, addr)
l.SetReadBuffer(maxDatagramSize)
for {
b := make([]byte, maxDatagramSize)
n, src, err := l.ReadFromUDP(b)
if err != nil {
log.Fatal("ReadFromUDP failed:", err)
}
h(src, n, b)
}
}
答案1
得分: 6
您的缓冲区 b
的大小适合最大可能的数据报包,但其中并不全是您的消息,只有前 n
个字节是消息的一部分。关于 illegal tag 0
和 wire type 0
的错误是由于尝试解析您未初始化的缓冲区空间中的 0
字节而引起的。将 b[:n]
传递给 Unmarshal
函数以修复该问题。
英文:
Your buffer b
is sized for the maximum possible datagram packet but not all of that is your message, only the first n
bytes. The messages about illegal tag 0
and wire type 0
result from trying to parse the 0
bytes in buffer space you haven't otherwise initialized. Pass b[:n]
to Unmarshal
to fix.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论