2

我的游戏和服务器的工作方式是这样的:

我发送以我创建的格式编码的消息。它以“p”开头,后跟消息长度的整数,然后是消息。

例如:p3m15 消息长 3 个字节。它对应于消息 15。然后解析消息,依此类推。

它是为 TCP 设计的,可能只发送 1 个字节(因为 TCP 只需要发送至少 8 位)。

我创建的这个消息协议非常轻量级并且效果很好,这就是为什么我在 JSON 或其他协议上使用它的原因。

我主要关心的是,客户端和服务器应该如何开始对话?

服务器希望客户端以我的格式发送消息。游戏将永远这样做。

我遇到的问题是当我在端口 1720 上测试我的服务器时。有 BitTorrent 流量,我的服务器正在接收它。这导致各种随机“客户端”连接到我的服务器并发送随机垃圾。

为了“解决”这个问题,我这样做是为了让客户端必须发送给我的第一件事是字符串“Hello Server”。

如果发送的第一个字节是 != 'H' 或者如果他们发送给我 > 12 个字节并且它是 != "Hello Server" 那么我立即断开它们。

这很好用。我只是想知道我做的事情是否有点天真,或者是否有更标准的方法来处理:

- 客户端开始与服务器通信 - 客户端通过 Hello Server 检查,但在某处我收到一条无效消息。我可以假设我的应用永远不会发送无效消息。如果是这样,那将是一个错误。现在,如果我检测到无效消息,那么我会断开客户端。

我注意到 BitTorrent 在每条消息之前都发送了“!!BitTorrent 协议”。我应该这样做吗?

任何关于这方面的建议并使其更安全和更有保障都会非常有帮助。谢谢

4

2 回答 2

2

也许是嵌入在您的消息中的幻数字段。

struct Message
{
    ...
    unsigned magic_number = 0xbadbeef3;
    ...
};

所以你收到东西后要做的第一件事就是检查magic_number字段是否为0xbadbeef3。

于 2013-01-07T00:19:54.193 回答
0

通常,我设计带有如下标头的协议:

typedef struct {
    uint32_t    signature;
    uint32_t    length;
    uint32_t    message_num;
} header_t;

typedef struct {
    uint32_t    foo;
} message13_t;

发送消息:

message13_t msg;
msg.foo = 0xDEADBEEF;

header_t hdr;
hdr.signature = 0x4F4C494D;         // "MILO"
hdr.length = sizeof(message13_t);
hdr.message_num = 13;

// Send the header
send(s, &hdr, sizeof(hdr), 0);

// Send the message data
send(s, &msg, sizeof(msg), 0);

接收消息:

header_t hdr;
char* buf;

// Read the header - all messages always have this
recv(s, &hdr, sizeof(hdr), 0);

// allocate a buffer for the rest of the message
buf = malloc(hdr.length);

// Read the rest of the message
recv(s, buf, hdr.length, 0);

该代码显然没有错误检查或确保所有数据都已发送/接收。

于 2013-01-07T00:23:31.547 回答