Go 是否可以将protobuf封送处理消息转到已分配的字节数组而不复制?
我正在通过自定义数据包实现客户机-服务器通信。 我正在使用GoGo 是否可以将protobuf封送处理消息转到已分配的字节数组而不复制?,go,protocol-buffers,ipc,packet,Go,Protocol Buffers,Ipc,Packet,我正在通过自定义数据包实现客户机-服务器通信。 我正在使用Gonet.conn。它可以拨打非常方便的tcp/unix方案。我使用协议缓冲区来定义我的消息 我定义了一个包含长度和缓冲区 type Packet struct { length uint32 buffer []byte } API函数如下所示: func(api*api)发送(m*proto.Message)错误 func(api*api)接收(p*数据包)错误 以send函数为例,它接收protobuf消息,将其封
net.conn
。它可以拨打非常方便的tcp/unix方案。我使用协议缓冲区
来定义我的消息
我定义了一个包含长度
和缓冲区
type Packet struct {
length uint32
buffer []byte
}
API函数如下所示:func(api*api)发送(m*proto.Message)错误
func(api*api)接收(p*数据包)错误
以send
函数为例,它接收protobuf消息,将其封送到数据包中
。并将其写入net.conn
以下是Send函数的简化版本:
func(api *API) Send(m *proto.Message) error {
bytes, err := proto.Marshal(m)
if err != nil {
return err
}
buffer := api.packet[:length]
copy(buffer, bytes)
_, err := api.conn.Write(buffer)
if err != nil {
return err
}
return nil
}
我正在将字节
复制到缓冲区
。因为Go协议缓冲区API只提供func封送处理(pb消息)([]字节,错误)
<>协议缓冲区C++
bool SerializeToArray(void*data,int size)const
,它序列化消息并将其存储在给定的字节数组中。
但我在Go协议缓冲区API中找不到同样的东西
如果我想直接将序列化结果存储在给定的字节数组中,有没有办法避免复制 不清楚你在问什么。请注意,proto Marshal()函数的作用正是您想要的:它将消息序列化为一个字节片(您可能指的是字节数组) 查看以下任一帮助:
func(api *API) Send(m *proto.Message) error {
p := Packet{}
p.buffer, err := proto.Marshal(m)
if err != nil {
return err
}
_, err := api.conn.Write(p.buffer)
if err != nil {
return err
}
return nil
}
或
似乎您可以将
数据包.buffer
作为
您正在从gogo/protobuf
中寻找方法,这是protobuf的另一个实现,与原始版本兼容
当您将要填充的缓冲区传递给同一缓冲区时,可以通过多个封送处理调用重复使用该缓冲区。显然,缓冲区应该足够大
func MarshalTo([]byte, m) error
你能澄清几件事吗:为什么数据包存储在API的字段中,这个长度是从哪里来的?你真的只想写一个由长度(4字节)组成的字节数组,然后将实际消息写入连接吗?接受答案怎么样?我的目的是将序列化缓冲区放入
数据包中,而不是直接将其写入conn
。因为包已经被其他组件用于我的项目。我不能重构它proto.Marshal
返回[]字节
,并被复制到我的数据包中。我正在寻找一种避免复制的方法。一个例子是原BuffC++ C++,它可以将消息整理成一个已经分配的缓冲区。但是go protobuf只能退回它。
type Packet struct {
length uint32
buffer proto.Buffer
}
...
var packet Packet
packet.length = YouLength
packet.buffer = proto.NewBuffer(make([]byte, YouLength))
//Then you can Marshall in Packet directly and it may be reused.
err := packet.Marshal(message)
func MarshalTo([]byte, m) error