简体   繁体   English

使用我自己的结构在套接字编程中填充 UDP 负载?

[英]Populate UDP payload in socket programming with my own structure?

I want to send a variable of custom struct over udp sockets using sendto().我想使用 sendto() 通过 udp 套接字发送自定义结构的变量。 This struct contains UDP payload.此结构包含 UDP 有效负载。 When I googled a bit, I found that it is possible to create raw socket in c using the flag, SOCK_RAW, while creating the socket.当我用谷歌搜索了一下时,我发现可以在创建套接字时使用标志 SOCK_RAW 在 c 中创建原始套接字。 But I think, then i will have to populate ip header as well as udp header too.但我认为,那么我也必须填充 ip 标头和 udp 标头。 I want to avoid that.我想避免这种情况。

But when I tried sending the custom structure over socket as mentioned above, I receive different data ( not the structure contents) when sniffed with wireshark.但是,当我尝试如上所述通过套接字发送自定义结构时,当使用wireshark 嗅探时,我收到了不同的数据(不是结构内容)。 Please help.请帮忙。

I tried changing the struct to normal uint32_t variable and used bit shifting operations to populate this variable.我尝试将结构更改为普通的 uint32_t 变量并使用位移操作来填充此变量。 I confirmed that this variable has exactly the contents that I intended to add to it.我确认此变量具有我打算添加到其中的内容。

But again, I am not able to send this too over sockets.但同样,我也无法通过套接字发送它。 Wireshark displays different content. Wireshark 显示不同的内容。 Is it because in sendto(), we provide the address of the buffer and not its value?是不是因为在 sendto() 中,我们提供的是缓冲区的地址而不是它的值?

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)); 

Expeced output is value of disc_req sent over socket and the same captured on wireshark.预期输出是通过套接字发送的 disc_req 的值,并且是在wireshark 上捕获的值。 But the actual value of disc_req is something different.但disc_req 的实际值有所不同。

The different content you are observing may be due to the sender and receiver having different endianess (host vs network).您观察到的不同内容可能是由于发送方和接收方具有不同的字节序(主机与网络)。 If so you will want to use hton...() and ntoh...() when working with multi-byte values.如果是这样,您将需要在处理多字节值时使用hton...()ntoh...()

In general, when you send an array or struct over UDP, treat it like a byte array.通常,当您通过 UDP 发送数组或结构时,将其视为字节数组。

Create a UDP socket, not a RAW socket:创建 UDP 套接字,而不是 RAW 套接字:

sockfd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );

Setup your destination address using the method you prefer (ie gethostbyname() )使用您喜欢的方法设置您的目标地址(即gethostbyname()

Then send the payload:然后发送有效载荷:

sendto( sockfd, ( char* ) &disc_req[0], sizeof( disc_req ), MSG_CONFIRM, (const struct sockaddr *) &servaddr, sizeof(servaddr));

To receive the payload:接收有效载荷:

recvfrom( sockfd, ( char* ) &disc_req[0], sizeof( disc_req ), 0, (const struct sockaddr *) &servaddr, sizeof(servaddr) );

The following is a complete example sending an NTP packet using UDP:以下是使用 UDP 发送 NTP 数据包的完整示例:

https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM