2016-11-18 148 views
0

如何以C++的UDP sendto结构发送数据?以UDP结构发送数据sendto

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) 
+1

错误,带有一个强制转换,'sizeof'而不是'strlen()',但是你不应该这样做。不要使用结构作为网络协议。 – EJP

回答

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提到这是一个非常糟糕的主意,你会很快与不同的实现结构的表示和领域遇到的问题(你会发现所有关于结构场填补之类)。

查看序列化机制(json,capnproto,protobufs,xml,asn.1什么)。


我现在认识到,“不,它不是”并非总是如此。显然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 
); 

想法(将指针传递给任何人想要的)的立场。

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)使用编译器扩展包装中顺序地结构数据,而不会因为对准的自由空间。在https://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86 中描述了这种方法,您可以将#pragma(用于gcc)添加到结构定义中,并使用指针和sizeof()发送它。 发送结构会是什么样子:

routingTable selfRoutingTable; 
unsigned char buf[1024]; 
memcpy(buf, &selfRoutingTable, sizeof(selfRoutingTable)); 

3)cnicutar劝使用XML或JSON发送数据。它速度较慢并且增加了数据包大小,但更容易支持和调试。