英文:
packing struct in golang in bytes to talk with C application
问题
我有一个基于golang的客户端,必须与一个C守护进程进行通信,使用二进制协议。我不能更改服务器以支持json、xml或其他协议。
在C代码中,我必须填充以下结构体并通过网络发送它:
typedef struct pkt_struct{
int16_t pkt_version;
int16_t pkt_type;
u_int32_t crc32_v;
int16_t ret_code;
char buffer[1024];
} pkt;
为了了解我需要的数据是什么样子的,它应该类似于以下输出:
$ irb
2.0.0-p353 :002 > [2, 1, 0, 0, 'version', 3].pack("nnNna1024n")
gob是答案吗?通过阅读文档,看起来不是。也许是ProtoBuf?
到目前为止,我做的是:
import "encoding/binary"
....
type NPacket struct {
packet_version int16
packet_type int16
crc32_value uint32
ret_code int16
buffer string
}
....
var pkt_send NPacket
pkt_send = NPacket{2,1,0,0,"version"}
buf := new(bytes.Buffer)
if err := binary.Write(buf, binary.BigEndian, &pkt_send); err != nil {
fmt.Println(err)
os.Exit(1)
}
我得到的错误是:
binary.Write: invalid type string
英文:
I have a golang based client that must to speak with a C daemon, using a binary protocol. I cannot change the server, to support json, xml or other protocol.
in the C code, i have to fill in the following struct and send it via network:
typedef struct pkt_struct{
int16_t pkt_version;
int16_t pkt_type;
u_int32_t crc32_v;
int16_t ret_code;
char buffer[1024];
}pkt;
to have an idea, how do I need the data, it should look like the output from:
$ irb
2.0.0-p353 :002 > [2, 1, 0, 0, 'version', 3].pack("nnNna1024n")
is gob the answer? reading through the documentation, looks that it is not. maybe ProtoBuf?
what I did until now is:
import "encoding/binary"
....
type NPacket struct {
packet_version int16
packet_type int16
crc32_value uint32
ret_code int16
buffer string
}
....
var pkt_send NPacket
pkt_send = NPacket{2,1,0,0,"version"}
buf := new(bytes.Buffer)
if err := binary.Write(buf, binary.BigEndian, &pkt_send); err != nil {
fmt.Println(err)
os.Exit(1)
}
error that I'm getting:
binary.Write: invalid type string
答案1
得分: 5
binary.Write
只适用于固定大小的对象。字符串可以是任意大小。相反,您可能希望复制您的 C 代码并使用固定大小的字节数组:
type NPacket struct {
packet_version int16
packet_type int16
crc32_value uint32
ret_code int16
buffer [1024]byte
}
您可以使用 copy(pkt.buffer[:], "string")
来设置缓冲区。
无论是 gob 还是 protobuf 都不是答案。它们都是编码格式,并且无法控制数据的编组方式。
英文:
binary.Write
only works on fixed sized objects. A string may be any size. Instead, you probably want to copy your C code and use a fixed size byte array:
type NPacket struct {
packet_version int16
packet_type int16
crc32_value uint32
ret_code int16
buffer [1024]byte
}
You can set the buffer with copy(pkt.buffer[:], "string")
.
Neither gob nor protobufs are the answer. They are both encoding formats and give you no control over how the data is marshalled.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论