为了账号安全,请及时绑定邮箱和手机立即绑定

在 go 中处理来自网络的原始字节

在 go 中处理来自网络的原始字节

Go
元芳怎么了 2021-09-10 17:29:01
(对不起,长问题!)我最近一直在尝试使用 Go 而不是 C++ 作为我作为副项目工作的游戏服务器模拟器,并质疑我是否正在以合理的 Go 术语实现它。正如您所料,服务器通过发送遵守特定协议规范的原始数据包 (TCP) 与一个或多个游戏客户端进行通信。相关部分是这样的:接收报头 -> 解密 -> 接收字节,直到达到报头长度 -> 解密数据包的其余部分 -> 分派给处理程序 -> 解码数据包 -> 必要时处理 -> 发送响应该协议是根据字节以小端顺序定义的,因此在我的 C++ 实现中,数据包标头如下所示(我知道,它仅适用于 LE 机器):struct pkt_header {    uint16_t length;    uint16_t type;    uint32_t flags;};在recv() 'ing 并解密此标头后,我将提取字段:// client->recv_buffer is of type u_char[1024]header = (pkt_header*) client->recv_buffer;if (client->recv_size < header->length) {    // Recv some more}// Decrypt and so on在处理程序本身中,我可以将上述头结构嵌套在其他数据包结构定义中,并将它们转换为byte[]缓冲区数组,以便直接访问字段。从我读到的内容来看,结构对齐(不出所料)在 Go 中是困难/不可能的,并且非常不鼓励。不知道还能做什么,我写了这个函数来从一个任意的 Struct -> []byte:// Serializes the fields of a struct to an array of bytes in the order in which the fields are// declared. Calls panic() if data is not a struct or pointer to struct.func StructToBytes(data interface{}) []byte {    val := reflect.ValueOf(data)    valKind := val.Kind()    if valKind == reflect.Ptr {        val = reflect.ValueOf(data).Elem()        valKind = val.Kind()    }作为 Go 新手,非常欢迎关于我如何更有效地实现这一点的反馈。到目前为止,它运行良好,但现在我面临着如何做相反的挑战:从 []byte->Struct (例如,[C8 00 03 00 00 01 00 00]到 Header { length = C8,大小 = 03,标志 = 0100 }我是否需要实现与此相反的方法,或者是否有更好的方法将字节数组转换为任意结构(反之亦然,而不是我的函数)?请让我知道是否有任何额外的澄清会有所帮助。
查看完整描述

1 回答

  • 1 回答
  • 0 关注
  • 187 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信