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

C 用我自己的结构在套接字编程中填充UDP有效负载?,c,udp,raw-sockets,C,Udp,Raw Sockets,我想使用sendto()通过udp套接字发送自定义结构的变量。此结构包含UDP有效负载。当我在谷歌上搜索一下时,我发现在创建套接字时,可以使用标记SOCK_raw在c中创建原始套接字。但我认为,然后我将不得不填充ip报头以及udp报头。我想避免这种情况 但是,当我尝试如上所述通过套接字发送自定义结构时,当使用wireshark嗅探时,我会收到不同的数据(而不是结构内容)。请帮忙 我尝试将结构更改为普通uint32_t变量,并使用位移位操作填充此变量。我确认这个变量的内容与我打算添加的内容完全相同

我想使用sendto()通过udp套接字发送自定义结构的变量。此结构包含UDP有效负载。当我在谷歌上搜索一下时,我发现在创建套接字时,可以使用标记SOCK_raw在c中创建原始套接字。但我认为,然后我将不得不填充ip报头以及udp报头。我想避免这种情况

但是,当我尝试如上所述通过套接字发送自定义结构时,当使用wireshark嗅探时,我会收到不同的数据(而不是结构内容)。请帮忙

我尝试将结构更改为普通uint32_t变量,并使用位移位操作填充此变量。我确认这个变量的内容与我打算添加的内容完全相同

但是,我不能通过套接字发送这个。Wireshark显示不同的内容。是因为在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是通过套接字发送的disc_req值,以及wireshark捕获的值。但是disc_req的实际值有所不同。

您观察到的不同内容可能是由于发送方和接收方具有不同的终端(主机与网络)。如果是这样,在处理多字节值时,您将希望使用
hton…()
ntoh…()

通常,当通过UDP发送数组或结构时,将其视为字节数组

创建UDP套接字,而不是原始套接字:

sockfd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
使用您喜欢的方法设置目标地址(即
gethostbyname()

然后发送有效载荷:

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) );
要接收有效载荷,请执行以下操作:

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数据包的完整示例:


我拼命想把它修好。@ikegami编辑。请现在检查。对不起,我累了。我想这是因为你奇怪地使用了数组。我认为
sendto(sockfd,disc_req,sizeof(disc_req),MSG_CONFIRM,(const struct sockaddr*)&servaddr,sizeof(servaddr))将解决我暂时使用此数组的问题。它将改为10号左右。最后,我需要完全通过socket发送数组内容使用原始套接字的原因是什么?如何创建套接字?谢谢。如何通过套接字发送完整的阵列,而不仅仅是disc_req[0]?我想以完全相同的顺序在wireshark中嗅探它。另外,您能解释一下如何从recvfrom()中的char*type返回数组吗?&on disc_req[0]是第一个元素的地址,sizeof(disc_req)是数组的整个长度。我编辑了答案,以包括如何接收数据包