使用我自己的结构在套接字编程中填充 UDP 负载?
Populate UDP payload in socket programming with my own structure?
我想使用 sendto() 通过 udp 套接字发送一个自定义结构变量。此结构包含 UDP 负载。当我搜索一下时,我发现可以在创建套接字时使用标志 SOCK_RAW 在 c 中创建原始套接字。但我认为,那么我将不得不填充 ip header 以及 udp header。我想避免这种情况。
但是,当我尝试如上所述通过套接字发送自定义结构时,在使用 wireshark 嗅探时,我收到了不同的数据(不是结构内容)。请帮忙。
我尝试将结构更改为正常的 uint32_t 变量,并使用位移操作来填充该变量。我确认此变量完全包含我打算添加到其中的内容。
但同样,我也无法通过套接字发送它。 Wireshark 显示不同的内容。是不是因为在sendto()中,我们提供的是buffer的地址而不是它的值?
uint32_t disc_req[1];
//disc_req is populated with bit shift operations in the following function
create_discovery_req(disc_req);
//now disc_req has exactly the required binary format - I confirmed this
// But the following sendto() sends different data. Confirmed over wireshark.
sendto(sockfd, &disc_req, sizeof(disc_req),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr));
预期输出是通过套接字发送的 disc_req 的值,并且在 wireshark 上捕获了相同的值。但 disc_req 的实际值有所不同。
您观察到的不同内容可能是由于发送方和接收方具有不同的字节顺序(主机与网络)。如果是这样,您将希望在处理多字节值时使用 hton...()
和 ntoh...()
。
通常,当您通过 UDP 发送数组或结构时,将其视为字节数组。
创建 UDP 套接字,而不是 RAW 套接字:
sockfd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
使用您喜欢的方法设置您的目标地址(即 gethostbyname()
)
然后发送payload:
sendto( sockfd, ( char* ) &disc_req[0], sizeof( disc_req ), MSG_CONFIRM, (const struct sockaddr *) &servaddr, sizeof(servaddr));
接收负载:
recvfrom( sockfd, ( char* ) &disc_req[0], sizeof( disc_req ), 0, (const struct sockaddr *) &servaddr, sizeof(servaddr) );
以下是使用UDP发送NTP数据包的完整示例:
https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html
我想使用 sendto() 通过 udp 套接字发送一个自定义结构变量。此结构包含 UDP 负载。当我搜索一下时,我发现可以在创建套接字时使用标志 SOCK_RAW 在 c 中创建原始套接字。但我认为,那么我将不得不填充 ip header 以及 udp header。我想避免这种情况。
但是,当我尝试如上所述通过套接字发送自定义结构时,在使用 wireshark 嗅探时,我收到了不同的数据(不是结构内容)。请帮忙。
我尝试将结构更改为正常的 uint32_t 变量,并使用位移操作来填充该变量。我确认此变量完全包含我打算添加到其中的内容。
但同样,我也无法通过套接字发送它。 Wireshark 显示不同的内容。是不是因为在sendto()中,我们提供的是buffer的地址而不是它的值?
uint32_t disc_req[1];
//disc_req is populated with bit shift operations in the following function
create_discovery_req(disc_req);
//now disc_req has exactly the required binary format - I confirmed this
// But the following sendto() sends different data. Confirmed over wireshark.
sendto(sockfd, &disc_req, sizeof(disc_req),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr));
预期输出是通过套接字发送的 disc_req 的值,并且在 wireshark 上捕获了相同的值。但 disc_req 的实际值有所不同。
您观察到的不同内容可能是由于发送方和接收方具有不同的字节顺序(主机与网络)。如果是这样,您将希望在处理多字节值时使用 hton...()
和 ntoh...()
。
通常,当您通过 UDP 发送数组或结构时,将其视为字节数组。
创建 UDP 套接字,而不是 RAW 套接字:
sockfd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
使用您喜欢的方法设置您的目标地址(即 gethostbyname()
)
然后发送payload:
sendto( sockfd, ( char* ) &disc_req[0], sizeof( disc_req ), MSG_CONFIRM, (const struct sockaddr *) &servaddr, sizeof(servaddr));
接收负载:
recvfrom( sockfd, ( char* ) &disc_req[0], sizeof( disc_req ), 0, (const struct sockaddr *) &servaddr, sizeof(servaddr) );
以下是使用UDP发送NTP数据包的完整示例:
https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html