英文:
Write at specific offset of bytes.Buffer
问题
我正在尝试编写一个游戏服务器,并需要创建发送回客户端的数据包。我将所有数据写入bytes.Buffer
,然后在获取字节并发送给客户端之前,我想在数据包前面添加数据包的总大小。
我考虑了以下代码:
// 每次创建数据包时调用`var b bytes.Buffer`是否会有问题?
func CreatePacket() []byte {
var b bytes.Buffer
// 大小
binary.Write(b, binary.LittleEndian, 0) // 插入到末尾
// 主体(可变数量的写入)
binary.Write(b, binary.LittleEndian, data)
// 更新偏移量为0处的大小
binary.Write(b, binary.LittleEndian, b.Len())
return b.Bytes()
}
但是我找不到任何方法来寻找或修改偏移量。
这段代码为什么不起作用?
var packet = b.Bytes()
// 大小实际上在偏移量2处,偏移量0是一个ID。
binary.LittleEndian.PutUint16(packet, uint16(0xF3))
binary.LittleEndian.PutUint16(packet, uint16(len(packet)))
请注意,我只会返回翻译好的部分,不会回答关于翻译的问题。
英文:
I'm trying to write a game server and need to create the packet I'll be sending back to the client. I am writing all the data into a bytes.Buffer
then I want to prefix the total size of the packet before getting the bytes and sending it to the client.
I was thinking of something like this:
// is it bad to call `var b bytes.Buffer` every time I create a packet?
func CreatePacket() []byte {
var b bytes.Buffer
// size
binary.Write(b, binary.LittleEndian, 0) // insert at end
// body (variable number of writes)
binary.Write(b, binary.LittleEndian, data)
// update the size at offset 0
binary.Write(b, binary.LittleEndian, b.Len())
return b.Bytes()
}
But I can't find any method to seek or modify the offset.
This doesn't work, why?
var packet = b.Bytes()
// the size is really at offset 2. offset 0 is an ID.
binary.LittleEndian.PutUint16(packet, uint16(0xF3))
binary.LittleEndian.PutUint16(packet, uint16(len(packet)))
答案1
得分: 1
你可以在组装数据包后直接将长度写入切片。你还需要指定长度前缀的大小,以确保在各个平台上都相同。
func CreatePacket(data []byte) []byte {
// 在开头留出4个字节用于ID和长度
b := bytes.NewBuffer(make([]byte, 4))
binary.Write(b, binary.LittleEndian, data)
packet := b.Bytes()
// 插入ID和前缀
binary.LittleEndian.PutUint16(packet, uint16(0xF3))
binary.LittleEndian.PutUint16(packet[2:], uint16(len(packet)))
return packet
}
链接:https://play.golang.org/p/35IX1c18a4
英文:
You can write the length directly to the slice after you have assembled the packet. You will also want to specify the length prefix size so that it is identical across platforms.
func CreatePacket(data []byte) []byte {
// leave 4 bytes at the start for the ID and length
b := bytes.NewBuffer(make([]byte, 4))
binary.Write(b, binary.LittleEndian, data)
packet := b.Bytes()
// insert the ID and prefix
binary.LittleEndian.PutUint16(packet, uint16(0xF3))
binary.LittleEndian.PutUint16(packet[2:], uint16(len(packet)))
return packet
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论