如何通过 UDP 发送结构并在另一端接收?
How to send a struct over UDP and receive on the other side?
我有一个关于套接字编程的非常具体的问题。我的代码类似于下面。
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 转换为 struct data_packet
来完成,因为底层字节布局是相同的。
可能的问题:
由于 struct
填充,代码可能会超出其范围。
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));
备选方案:使 buffer[]
足够大
// char buffer[501];
char buffer[sizeof packetosend];
只发送数据而不发送任何填充:
使用特定于实现的关键字(如果可用)打包数据
// struct data_packet{
packed struct data_packet{
或执行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[]
大小以匹配。
我同意 Dennis Afanasev 的观点。详细说明转换策略,读取所有 501 个字节(包括 partial/incomplete 读取),然后转换为指针变量,例如:
struct data_packet *dataRecv = (struct data_packet *)&recvbuffer[0];
然后您可以取消引用 dataRecv 以访问该结构,如 dataRecv->seqnumber 和 dataRecv->data。
我有一个关于套接字编程的非常具体的问题。我的代码类似于下面。
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 转换为 struct data_packet
来完成,因为底层字节布局是相同的。
可能的问题:
由于 struct
填充,代码可能会超出其范围。
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));
备选方案:使 buffer[]
足够大
// char buffer[501];
char buffer[sizeof packetosend];
只发送数据而不发送任何填充:
使用特定于实现的关键字(如果可用)打包数据
// struct data_packet{
packed struct data_packet{
或执行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[]
大小以匹配。
我同意 Dennis Afanasev 的观点。详细说明转换策略,读取所有 501 个字节(包括 partial/incomplete 读取),然后转换为指针变量,例如:
struct data_packet *dataRecv = (struct data_packet *)&recvbuffer[0];
然后您可以取消引用 dataRecv 以访问该结构,如 dataRecv->seqnumber 和 dataRecv->data。