C 如何通过UDP发送结构并在另一端接收?

C 如何通过UDP发送结构并在另一端接收?,c,sockets,networking,udp,C,Sockets,Networking,Udp,我有一个关于套接字编程的非常具体的问题。我的代码类似于下面的代码 struct data_packet{ unsigned char seqnumber; char data[500]; } struct data_packet packettosend; packettosend.seqnumber = '0' packettosend.data = 'some binary data' (this could be any length from 0 bytes to 5

我有一个关于套接字编程的非常具体的问题。我的代码类似于下面的代码

struct data_packet{
   unsigned char seqnumber; 
   char data[500]; 
}

struct data_packet packettosend; 
packettosend.seqnumber = '0'
packettosend.data = 'some binary data' (this could be any length from 0 bytes to 500 bytes) 

//sender code 
char buffer[501]; 
memcpy(buffer, &packettosend, sizeof(packetosend)); 
int s = sendto(socketfd, buffer, sizeof(buffer), 0 , .......other params); 

//receiver code
char recvbuffer[501];
int t = recvfrom(recvsocketdf, recvbuffer, 501, 0 ....other params);
  
How do I set up my receiver to receive the data and save it on a `struct data_packet`?    

seqnumber是一个1字节的字符,数据可以是0字节到500字节

我正在使用
sendto
发送缓冲区,并使用
recvfrom
在另一端接收缓冲区


我如何在接收端接收我的seqnumber和数据?我对C和Socket编程非常陌生。非常感谢您的帮助。

我的第一个建议是在填充和发送缓冲区之前将其归零,以避免垃圾值。您需要定义一个协议-您只能通过网络发送和接收原始字节。这样,接收端将第一个字节解释为序列号,其余字节解释为实际消息本身。这可以通过简单地将recvbuffer强制转换为结构数据包来实现,因为底层字节布局是相同的。

可能的问题:

由于structpadding,代码可能在其边界之外写入

struct data_packet{
   unsigned char seqnumber; 
   // There maybe padding here.
   char data[500]; 
   // There maybe padding here.
}

struct data_packet packettosend; 
char buffer[501];  // May be too small for `packettosend`
memcpy(buffer, &packettosend, sizeof(packetosend)); 
备选方案:使缓冲区[]足够大

// char buffer[501];
char buffer[sizeof packetosend];

要仅发送数据而不发送任何填充,请执行以下操作:

使用特定于实现的关键字打包数据(如果可用)

或执行2次发送

int s1 = sendto(socketfd, &buffer.seqnumber, sizeof buffer.seqnumber, ...);
int s2 = sendto(socketfd, buffer.data, sizeof buffer.data, ...);
或者仔细复制

#define SEQ_DATA (sizeof buffer.seqnumber + sizeof buffer.data)
char buffer[SEQ_DATA]; 
memcpy(buffer, &buffer.seqnumber, sizeof buffer.seqnumber);
memcpy(buffer + sizeof buffer.seqnumber, buffer.data, sizeof buffer.data);
int s = sendto(socketfd, buffer, sizeof buffer, ...);

调整
recvbuffer[]
大小以匹配。

我同意丹尼斯·阿法纳塞夫的观点。要详细说明转换策略,请读取所有501字节(包括部分/不完全读取),然后转换为指针变量,例如:

struct data_packet *dataRecv = (struct data_packet *)&recvbuffer[0];

然后,您可以解除对dataRecv的引用以访问该结构,如dataRecv->seqnumber和dataRecv->data中所述。

您只需要一个缓冲区来接收它,就像从中发送它一样。然后,您可以检查作为
数据包收到的数据包(假设大小正确)是的,但当我发送的数据小于500字节时,数据似乎在末尾有垃圾值。如果您只收到与您发送的数据相同的数据,那么读取超出此值的数据就是一个错误
recvfrom
确实会告诉您收到了多少字节,您应该使用这些信息。感谢您花时间处理这些信息。这看起来很有希望。我需要遵循某些条件。我只能执行1次发送。我收到的数据包的大小不能超过501字节。我该如何解决这个问题?@MaheshKhanal使用最后一份“小心”谢谢。照着原意复制作品。我非常感激。
struct data_packet *dataRecv = (struct data_packet *)&recvbuffer[0];