在UDP sendto中以结构形式发送数据

时间:2016-11-18 21:33:55

标签: c++ networking

如何在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)

2 个答案:

答案 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发送数据。它速度较慢,增加了数据包大小,但更容易支持和调试。