C-使用htonl和ntohl封送/解封送结构

C-使用htonl和ntohl封送/解封送结构,c,struct,marshalling,unmarshalling,memcpy,C,Struct,Marshalling,Unmarshalling,Memcpy,所以我在c中有一个结构,我需要通过UDP套接字发送它。RPCmessage应扁平化为一个字节数组,即message.data。然后通过UDP套接字发送message.data typedef struct { enum {Request, Reply} messageType; /* same size as an unsigned int */ unsigned int RPCId; /* unique identifier */ unsigned int proced

所以我在c中有一个结构,我需要通过UDP套接字发送它。RPCmessage应扁平化为一个字节数组,即message.data。然后通过UDP套接字发送message.data

typedef struct {
    enum {Request, Reply} messageType; /* same size as an unsigned int */
    unsigned int RPCId; /* unique identifier */
    unsigned int procedureId; /* e.g.(1,2,3,4) for (+, -, *, /) */
    int arg1; /* argument/return parameter */
    int arg2; /* argument/return parameter */
    /* each int (and unsigned int)is 4
    bytes */
} RPCmessage;

typedef struct {
    unsigned int length;
    unsigned char data[SIZE];
} Message;
我对c还远远不够精通,所以我不知道如何将其扁平化为通过套接字发送的字节数组。我相信我需要使用htonl()进行封送,使用ntohl()进行解封送。但我无法让我的记忆按照我需要的方式表现。目前我收到一条警告:从不同大小的整数转换为指针[-Wint到指针转换]

void marshal(RPCmessage *rm, Message *message){
    memcpy(&message->data[0], (char *)htonl(rm->messageType), sizeof(rm->messageType));
    memcpy(&message->data[4], (char  *)htonl(rm->RPCId), sizeof(rm->RPCId));

    /* more marshaling follows for the other 4 members */
}
希望很简单?但是当这个问题解决后,我肯定我会遇到将字节数组解组回RPCmessage结构的问题。我的猜测是这样做。。。但我不知道如何让它回到主机秩序与ntohl

void unMarshal(RPCmessage *rm, Message *message){
    //here, I am assuming *message is the message received from the socket
    memcpy(rm->messageType, message->data[0], sizeof(rm->messageType));
    memcpy(rm->RPCId, message->data[4], sizeof(rm->RPCId));

    /*more unmarshaling...*/

}
我一直在阅读手册页,但没有点击。指针目前有点超出我的理解范围,我正在努力更好地理解它们。
提前感谢您救了我的命。

函数返回类型为
uint32\u t
的值。它不是指针,所以将它转换为指针是没有意义的。这就是警告告诉你的

您需要将结果存储在temp变量中,然后将temp的地址传递给
memcpy

uint32_t msgType = htonl(rm->messageType);
uint32_t rpcId = htonl(rm->RPCId);
memcpy(&message->data[0], &msgType, sizeof msgType);
memcpy(&message->data[4], &rpcId, sizeof rpcId);

顺便说一句,对您的数据结构执行正确的封送/解封,而不是试图获取结构的地址来发送/接收数据结构,这是值得称赞的。

(char*)htonl(rm->messageType)
noooooooo,
uint32\u t some temp\u var=htonl(rm->messageType)
然后
memcpy(…..&some temp\u var)
。另外,
unsigned int
可能少于32位,我建议
uint32\u t
uint32\u t
unsigned long
。真漂亮!这将删除编译错误,但是message.data的每个索引都是空字符。@Nate这是另一个需要新问题的问题。另外,如果你觉得它有用的话,请随意回答。一旦整个问题解决了,我很乐意接受这个答案。因为我有一个空字符串,我不能客观地知道这是正确的答案。我希望这是有道理的。我将发布一个新问题,一旦我看到字符串已填充,并且我不必更改您的memcpy,我保证接受您的回答:)