现在,我正在为我的在线游戏编程网络,我不太确定 如何处理接收数据。 问题是我无法猜测数据包的大小,所以我想从数据包中读取4个字节并将它们转换为int以了解数据包的大小。 然后我只是创建一个大小的缓冲区并接收其余的数据包,这是一个好主意吗?
为了您的信息,我使用的是非阻塞的i / o。
答案 0 :(得分:1)
您的方法听起来很合理 - 您实际上将消息大小嵌入到消息头中,这可能是在您的情况下处理它的最强大的方法。或者,您可以使用固定长度数据包(ick)或使用某种分隔符(对于二进制消息,它根本不能正常工作)。
此链接socket-protocol-fundamentals包含一些可能有用的其他信息。
答案 1 :(得分:0)
如果您使用的是TCP套接字,请不要依赖数据包大小。数据流是字节流,而不是数据包流。
答案 2 :(得分:0)
如果你不小心,你提出的建议是一个安全漏洞。所以要非常好吃 - 尤其是在信任网络输入的时候。
您没有指定TCP或UDP,所以我只是给您一些一般指导。
对于TCP或UDP,只需分配一个大小为N的缓冲区,其中N是您可能从远程播放器或服务器发送的最大邮件大小。对于UDP,我建议将其保持在1500字节以下。对于TCP,您可以拥有更大的尺寸。
对于您的套接字,无论是UDP还是TCP,都将其设置为非阻塞。这样你就不会在等待数据时挂起游戏循环。
将大小和crc-hash添加到任何邮件的标头中。当您收到作为UDP数据包的消息时,如果数据包标头中的大小大于N(这意味着您已经有截断的数据包)或者散列与您在接收大小上计算的内容不匹配,则只需拒绝包。我之所以这样称呼是因为没有额外的完整性检查,黑客和骗子会利用你的数据包结构来赢得胜利。
对于TCP,您实际上是按照描述的方式构建消息。每条消息都有一个标题,指示要遵循的字节数。但是做同样的事情,我呼吁UDP - 添加自己的标头进行完整性检查。如果您收到邮件损坏和ASSERT,请关闭套接字。
在TCP中,由于TCP分段,您可能无法在同一“recv”调用中收到整个消息。也就是说,如果您只收到部分消息,请将其存储在临时缓冲区中。在随后调用recv(在下一个游戏帧上)时,追加到此缓冲区。您必须保留变量以跟踪消息的预期结束,这样您就不会意外地读入可能已发送的下一条消息。
祝你好运。