我正在使用unix套接字,当我的缓冲区是char类型(即发送和接收字符串)时,我可以发送()和recv()数据 . 我使用了Beej的套接字指南,所用的例子是发送/接收字符串 .
现在我想在一条消息中发送/ recv不同类型的数据 .
例如,在一条消息中,我想发送一个整数,一个字符串,一个double和一个float . 我应该怎么做呢?更具体地说,我的消息'buffer'应该是什么类型的?
send和recv的原型:
int recv (int socket, void *buffer, size_t size, int flags)
int send (int socket, void *buffer, size_t size, int flags)
我没有太多的C / C和指针经验,所以这可能是一个noob问题 .
如果有人能指导我朝着正确的方向前进,我真的很感激 . 谢谢
5 回答
除非您计划发送大量数据(许多千字节)并经常(每秒几个数据包),否则我建议您将数据转换为字符串(也称为“序列化数据”)并以此方式传递 . 它有几个好处:
它是可移植的 - 无论
int
或float
或double
的大小是什么 - 或者结构中字段之间的填充是什么 .它很容易调试(您只需查看数据并说明它是对还是错)
发送/接收机器的字节顺序无关紧要 .
另一方面,发送二进制数据很复杂,因为您需要担心数据字段的各个大小及其内部表示(字节顺序,如何在二进制中重新表示
double
,结构内数据字段的填充,不能通过指针等等) . 唯一的好处是二进制数据更紧凑 . 但这只会影响你是否有很多千字节和/或每秒发送大量数据包 .您需要发送方的serialize对象,并在接收方反序列化 . 在C中有许多库,例如Boost Serialization或者如果您想重新发明轮子,您可以随时自行滚动 .
最好的方法是封装您想要在结构中传递的信息 . 然后传递结构的地址和长度 . 请注意
buffer
是void*
所以这允许您传递包含您的信息的结构的地址 .这是我用于安全拷贝工具的
struct
的一小部分片段,然后在
send_message()
序列化message
然后write
序列化为socket
正如@vitaut所建议的那样,你可以使用一个库来实现
serialize
,我将它作为一种学习体验来实现 .那么,要回答问题(“我如何发送结构?”),你只需发送一个指向结构的指针 .
它真的很容易 . 现在,另一方必须是相同的(也就是说,系统A内存中的结构必须与系统B上的结构相匹配) . 更好的方法是使用更具体的类型和一些函数来正确排序数据:
当你想“通过网络”“移植”发送二进制数据时,你可以看到它开始变得系统特定,这就是为什么人们要转换为文本,或者很可能使用已经编写的序列化库 .
这取决于这必须是多么便携 .
最简单的方法是将所有内容转换为ASCII,用逗号或分号分隔,然后在接收端再次解析它 .
您也可以将其转换为network byte order并将其作为二进制发送 .