DHCP over UDP 发送问题

发布于 2024-10-12 18:19:44 字数 831 浏览 4 评论 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));

如何发送此消息?

I am trying to make a simple DHCP client. It should send a message to DHCP server (already have this) receive a message back and parse it.
I have created a 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
};

If I fill all fields with according data how to send this with sendto()? Should i parse it into char and send a pointer as sendto() requaries a pointer as a second parameter.

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

How to send this message?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

神也荒唐 2024-10-19 18:19:44

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

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

UPDATE

在 Linux 和 Windows 中 sendto 函数有点不同,正如我们在这个答案的评论中发现的那样。因此,我们应该分别针对 Linux 和 Windows 使用 (void *)(char *) 转换。

关于字节顺序:您也应该小心它。但它应该可以很好地适应所有 x86 CPU。我使用过的唯一“错误”的字节序系统是基于 IBM Power6 的超级计算机。

First of all you must say to your compiler not to add any paddings into structures. And then you can do:

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

UPDATE

In Linux and Windows sendto function are a bit different as we figured out in comments to this answer. So we should use (void *) and (char *) conversion for Linux and Windows respectively.

About endianess: you should be also careful about it. But it should fork fine for all x86 CPUs. The only "wrong" endian style system I've ever used was a super computer based on IBM Power6.

如何视而不见 2024-10-19 18:19:44

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

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

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

并且不要忘记您的编译器可能会向结构添加 填充字节 到结构中,因此其大小可能会变为比你想象的要大。

You just need to pass the address of the buffer to sendto. No matter what type it will have - what really matters for sendto is the bytes there.

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

The length of your message will be sizeof(struct dhcp_msg).

And don't forget that your compiler may add padding bytes to the struct, so its size may become bigger than you expect.

茶色山野 2024-10-19 18:19:44

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

真正存在的问题是指针类型转换错误:MSVC拒绝将struct dhcp_msg*作为< code>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* 类型转换)变体)。

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

Let me start a new answer, as others have too much comments which are hard to dig in.

The problem which OP really has is a pointer type conversion error: MSVC refuses to pass struct dhcp_msg* as a const char* argument, and no explicit conversions help.

#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;
}

This source is not intended to be run, but it compiles fine with my GCC 4.4.5 (as well as void* and char* typecasting variants).

Ok, problem solved by doing typecasting carefully.

缱倦旧时光 2024-10-19 18:19:44

将 struct dhcp_msg 转换为 char*

cast your struct dhcp_msg into a char*

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文