如何在将结构发送到另一个进程时知道数据表示

how to know the data representation when sending a struct to another process

本文关键字:进程 另一个 数据表示 结构      更新时间:2024-05-10

假设我想将数据从一个进程(1(传输到另一个进程。

struct test {
uint8_t a;
uint8_t b;
}

该结构通过缓冲器发送。我使用第二个进程的功能来传输数据。

write(unsigned char* buffer, int size)

我主要做

int main(){
test sendData;
unsigned char buffer[2]
sendData.a = 10;
sendData.b = 20;
std::memcpy(buffer,&sendData,sizeof(test));
_device.write(buffer, sizeof(buffer));// assume that _device is my second process instance
}

我如何知道使用哪个数据表示与第二个进程通信?

它是大端序还是小端序?还是取决于处理器体系结构?我怎么知道呢?

是否已经有_device.write((以任何方式工作?这本身可能很棘手,涉及到启动过程设置输入和输出文件或进行套接字编程。这是一个比你问的更大的问题。你基本上已经问过二进制表示法。

如果您的两个进程在同一台计算机上运行,并且结构的源代码定义相同,那么对原始数据进行简单的写入是安全的。

但是,如果您的进程在网络上运行,可能在不同类型的硬件上运行,那么您绝对不能依赖原始写入,因为您不知道您的端序是否匹配。

所以你有两个基本的选择。可以将数据序列化为外部表示形式。除非你发送了大量数据,否则大多数人可能会这样做。例如,你可以将其转换为JSON字符串并发送。这就是很多HTTPREST调用所做的

另一种选择是使用网络字节顺序调用。你不会读或写原始对象。您可以编写一个读取或写入它的方法,它将使用htonshtonl等调用。

就我个人而言,我已经几十年没有这样做了。网络速度很快,而且大多数数据都很小。您很可能会使用JSON。

除非你在写MMORPG。

网络上的通信有不同的层。在您的示例中,缺少2层。我看不出你在使用哪个传输层,但我假设是TCP套接字。TCP套接字是流传输层。这意味着,当你向目的地发送多条消息时,它将不知道一条消息的起点或终点。读取功能会给您不完整的信息。

因此,您缺少的第一层是一个协议,它可以跟踪完整的消息。您可以使用包含消息长度的标头,也可以在每条消息的末尾使用分隔符。为了知道目的地的消息类型,您可以在协议中给出消息的名称。例如,可以在协议标头中对消息名称进行编码。

缺少的第二层是数据编码,它解决了具有不同平台(字节顺序、数据对齐(的问题。在这里,您可以使用json或protobuf。

有可用的框架,可以解决您的问题。其中一个被称为finalmq:https://github.com/bexoft/finalmq

在自述中,它还解释了不同的层次。在每一层上,您可以选择不同的替代方案。例如:

带有换行分隔符的json
  • 带有消息头的protobuf
  • json和http(您可以使用浏览器访问服务器(
  • protobuf与MQTT(用于物联网应用程序(