C/C++ 中的套接字编程 - 接收由 typedef 结构定义的消息

Socket Programming in C/C++ - receiving a message defined by a typedef struct

本文关键字:typedef 结构 消息 定义 C++ 套接字 编程      更新时间:2023-10-16

关于我的套接字程序的问题:我有一个... 内部类...我猜(对不起,从 Java 到 C/C++),它是:

typedef struct {
    enum {Request, Reply} messageType;
    unsigned int RPCId;
    unsigned int procedure;
    int arg1;
    int arg2;
} RPCMessage;

我希望收到一个 RPCMessage 作为对通过 UDP 套接字发送的请求的响应。目前,我收到带有代码的消息:

/* Recv a response */
fromSize = sizeof(fromAddr);
if ((respSize = recvfrom(sock, buffer, maxSize, 0, (struct sockaddr *)&fromAddr,
        &fromSize)) != messageSize)
    DieWithError("recvfrom() failed");

我应该注意,这里的缓冲区是一个字符数组。我想要的是将收到的消息变回 RPCMessage...所以我尝试了:

RPCMessage receivedMessage = (RPCMessage)buffer;

这并没有让编译器高兴...将 char 数组中的这些字节排列回 RPCMessage 及其字段的正确方法是什么?

你几乎没有选择。选项 #1 是复制缓冲区的内容:

RPCMessage receivedMessage;
memcpy(&receivedMessage, buffer, sizeof(receivedMessage));

选项 #2 是将指向 char 缓冲区的指针重新解释为 RPCMessage 类型的指针:

RPCMessage *receivedMessage = (RPCMessage *)buffer;

选项编号 #3 是手动将缓冲区解析为类 RPCMessage 的字段。

对于选项 #1 和 #2,您必须了解结构/字段填充、架构的对齐要求等。

首先,您正在处理原始字节,因此请使用无符号字符数组,不要意外的符号扩展。

其次,您需要一个指针类型来引用该缓冲区:

RPCMessage* receivedMessage = (RPCMessage*)buffer;

最后,确保发送方和接收方使用相同的字节打包。同样,在执行上述操作之前,请确保您收到了 RPCMessage 的所有数据。

注意:通常,您最好将字节从缓冲区中拆解出来,并在 RPCMessage 结构中制造接收到的数据,除非您确定双方在打包、字节序等方面达成一致。