0

我正在尝试制作一个简单的 DHCP 客户端。它应该向 DHCP 服务器发送一条消息(已经有这个)接收一条消息并解析它。我创建了一个结构

struct dhcp_msg{
 _int8 op;  //opcode
 _int8 htype; //hardware type
 _int8 haddr; //hardware adress
 _int8 hops;  //hop count

 _int32 tid;  //transaction id

 _int16 sec;  //seconds
 _int16 unused; //unused

 _int32 cipaddr;  //client ip
 _int32 yipaddr;  //your ip
 _int32 sipaddr;  //server ip
 _int32 gipaddr;  //gateway ip

 char chaddr[16]; //client hardware address
 char sname[64];  //server name
 char bname[128]; //boot file name

 _int8 mcookie[4];  //magic cookie
};

如果我用相应的数据填写所有字段,如何使用 sendto() 发送?我是否应该将其解析为 char 并发送一个指针,因为 sendto() 将指针作为第二个参数。

char *buffer;
...?
sendto(socketC, buffer, sizeof(buffer), 0, (SOCKADDR *)&servAddr, sizeof(sockaddr_in));

如何发送此消息?

4

4 回答 4

4

首先你必须告诉你的编译器不要在结构中添加任何填充。然后你可以这样做:

struct dhcp_msg my_msg;
// Fill my_msg
sendto(socket, (void *) &my_msg, ...)

更新

正如我们在对此答案的评论中发现的那样,在 Linux 和 Windows中,sendto功能有点不同。所以我们应该分别为Linux和Windows使用(void *)和转换。(char *)

关于字节序:你也应该小心它。但它应该适用于所有 x86 CPU。我曾经使用过的唯一“错误”的字节序样式系统是基于 IBM Power6 的超级计算机。

于 2011-01-15T16:18:52.230 回答
1

您只需要将缓冲区的地址传递给sendto. 不管它有什么类型——真正重要的sendto是那里的字节。

struct dhcp_msg msg;
// fill in all fields...
sendto(socketC, &msg, sizeof(struct dhcp_msg), ...);

您的消息长度将是sizeof(struct dhcp_msg).

并且不要忘记您的编译器可能会向结构添加填充字节,因此它的大小可能会变得比您预期的要大。

于 2011-01-15T16:19:14.410 回答
0

让我开始一个新的答案,因为其他人有太多难以挖掘的评论。

OP 真正遇到的问题是指针类型转换错误:MSVC 拒绝struct dhcp_msg*作为const char*参数传递,并且没有显式转换帮助。

#include <sys/socket.h>

struct test {
    int a;
    int b;
};

int main() {
    struct test t;
    t.a = 3;
    t.b = 5;
    send(1, &t, sizeof(struct test), 0);

    return 0;
}

此源代码不打算运行,但它可以与我的 GCC 4.4.5(以及类型转换变体)一起编译。void*char*

好的,通过仔细进行类型转换解决了问题。

于 2011-01-15T16:55:22.957 回答
-2

将您的 struct dhcp_msg 转换为 char*

于 2011-01-15T16:19:44.973 回答