我正在尝试制作一个简单的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));
如何发送此消息?
答案 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 *