packing struct in golang in bytes to talk with C application

huangapple go评论90阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2014年4月20日 03:14:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/23174362.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定