2014-10-19 123 views
1

所以我尝试使用sendto()函数向客户端发送消息。在sendto()函数中发送一个结构 - C语言

和sendto()函数的原型是这样的:

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, 
       const struct sockaddr *dest_addr, socklen_t addrlen); 

但我想送一个结构作为第二个参数。我能做到吗?或者buf必须是一个字符串?

编辑:你看,我都能够发送这样的:

“的消息由‘标题’,其次是‘有效载荷’

你的消息头应该包括以下内容:

uint8_t version; /* must be 1. If you receive anything else, discard*/ 
uint8_t ttl; /* must be 1. If you receive anything else, discard*/ 
uint16_t payload_length; /* bytes following the header */ 
uint32_t account_identifier; /* digits of your account name */ 
uint32_t source_address; /* unused for now, set to 0 and ignore. */ 
uint32_t destination_address; /* unused for now, set to 0 and ignore. */ 
uint16_t checksum; /* unused for now, set to 0 and ignore. */ 
uint16_t protocol; /* must be 1. If you receive anything else, discard*/" 

和有效载荷是一个文本字符串,如“你好”之类的。

我觉得像我送头将发送所有的结构的唯一方式信息。对?

回答

2

您可以使用sendto发送任何连续的内存块,因此不带指针的struct就可以。但是,客户需要能够使用适当的布局来处理该struct,这是非常有限的。

考虑一个简单的struct这样的:

struct One { 
    int a; 
    float b; 
    char c[20]; 
}; 

它可以在同一硬件上,当客户端和服务器端的代码被编译相同的编译器,使用相同的设置罚款。即使对于看起来很简单的struct来说,稍微不同的硬件也会导致问题,尽管:endianness,填充,各种表示的大小等都将相同以使其工作。

如果您需要与其他硬件或其他编程语言的互操作性,您需要生成双方都可以处理的特定结构,二进制或文本。

如果您struct有一个指针,你将无法发送和接收它没有一些特殊的处理:

struct Two { 
    int a; 
    float b; 
    char* c; // <<<=== Not going to work 
}; 

当您需要发送的结构一样,你发件人“连载”他们转换为可由接收端“反序列化”的字节数组,然后发送该缓冲区。接收此缓冲区的代码将数据“解包”为一个“struct”,根据需要分配内存,并将接收缓冲区中的数据复制到这个新分配的内存中。

struct以上可以如下被序列:表示长度块的len由指针指向

  • 4个字节用于int
  • 4个字节用于float
  • 4字节c
  • len字节代表内容c
+0

雅互操作性不成问题。服务器的硬件是一样的。 – umdcoder 2014-10-19 21:01:15

+0

带指针的结构体是否也能发送? – umdcoder 2014-10-19 21:01:41

+1

@umdcoder不,它不是。一般来说,发送结构是一个糟糕的主意。不要使用结构作为网络协议。使用网络协议作为网络协议。 – EJP 2014-10-19 21:04:21