DHCP over UDP发送问题

时间:2011-01-15 16:13:36

标签: c++ udp dhcp

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

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 个答案:

答案 0 :(得分:4)

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

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

<强>更新

在Linux和Windows中,sendto函数有点不同,正如我们在评论中找到的那样。因此,我们应分别对Linux和Windows使用(void *)(char *)转换。

关于endianess:你也应该小心。但它应该适用于所有x86 CPU。我用过的唯一“错误”的endian风格系统是基于IBM Power6的超级计算机。

答案 1 :(得分:1)

您只需将缓冲区的地址传递给sendto即可。无论它有什么类型 - sendto真正重要的是那里的字节。

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

邮件的长度为sizeof(struct dhcp_msg)

不要忘记你的编译器可能会在结构中添加padding bytes,因此它的大小可能比你预期的要大。

答案 2 :(得分: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*类型转换变体)编译

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

答案 3 :(得分:-2)

将你的struct dhcp_msg转换为char *