如何在C ++中以UDP sendto格式发送struct中的数据?
struct routingTable{
int numServers;
int numNeighbors;
int selfId,neighborNode[5];
int Cost[6][6];
};
routingTable selfRoutingTable;
sendto(listener_socket,<This is a char *> , strlen(my_message), 0, (struct sockaddr *)&nbaddr, sizeof(nbaddr)
答案 0 :(得分:3)
sendto(listener_socket,<This is a char *> , strlen(my_message), 0, (struct sockaddr *)&nbaddr, sizeof(nbaddr)
不,不是,它是const void *
。来自a man page:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
从技术上讲,您可以使用&selfRoutingTable
发送结构,并使用sizeof
作为尺寸,但请参见下文。
正如EJP所说,这是一个非常糟糕的主意,你很快会遇到结构及其字段在不同实现上的表示问题(并且你会发现所有关于struct字段填充等的问题) )。
查看序列化机制(json,capnproto,protobufs,xml,asn.1任何东西)。
我现在意识到&#34;不,它不是&#34;并非总是如此。显然是MSDN lists sendto as taking a const char *
。
int sendto(
_In_ SOCKET s,
_In_ const char *buf,
_In_ int len,
_In_ int flags,
_In_ const struct sockaddr *to,
_In_ int tolen
);
将指针传递给任何想要的东西的想法都代表着。
答案 1 :(得分:0)
有几种方法:
1)手动将数据打包到内存缓冲区。 对于x64处理器:
unsigned char *buf = new unsigned char[1024];
unsigned char *p = buf;
*(int *)p = rt.numServers; p += sizeof(int);
*(int *)p = rt.numNeigbors; p += sizeof(int);
这样每个值在缓冲区中都有固定的偏移量,具体取决于发送端的int大小。接收方需要从接收缓冲区解包数据:
unsigned char *buf;
int *p = buf;
rt.numServers = *p; p++;
发送方和接收方可能具有不同的int大小,因此您可能需要更改代码。
打包数据的另一种方式(对于32位int)将是:
unsigned char *buf;
buf[0] = rt.numServers & 0xff000000;
buf[1] = rt.numServers & 0x00ff0000;
buf[2] = rt.numServers & 0x0000ff00;
buf[3] = rt.numServers & 0x000000ff;
buf[4] = rt.numNeighbors & 0xff000000;
2)由于对齐,使用编译器扩展按顺序打包struct中的数据而没有可用空间。它在https://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86描述 这样,您可以将#pragma(对于gcc)添加到结构定义,并使用pointer和sizeof()发送它。 发送结构看起来像:
routingTable selfRoutingTable;
unsigned char buf[1024];
memcpy(buf, &selfRoutingTable, sizeof(selfRoutingTable));
3)因为cnicutar建议使用xml或json发送数据。它速度较慢,增加了数据包大小,但更容易支持和调试。