简体   繁体   English

C ++ IPC通讯

[英]C++ IPC Communication

I am in dilema to make decision on the below scenarios. 我在以下情况下无法做出决定。 Kindly need experts help. 请需要专家的帮助。

Scenario : There is TCP/IP communication between two process running in two boxes. 方案:在两个框中运行的两个进程之间存在TCP / IP通信。

Communication Method 1 : Stream based communication on the socket. 通信方法1:在套接字上基于流的通信。 Where on the receiver side , he will receive the entire byte buffer and interpret first few fixed bytes as header and desrialize it and get to know the message length and start take message of that length and deserialize it and proceed to next message header like that goes on.... 在接收方的哪里,他将接收整个字节缓冲区,并将前几个固定字节解释为标头,然后对其进行反序列化,从而了解消息长度,并开始获取该长度的消息并反序列化,然后继续进行下一个消息标头,如下所示:上....

Communication Method2 : Put all the messages in a vector and vector will be residing in a class object. 通讯方式2:将所有消息放入向量中,向量将驻留在类对象中。 serialize the class object in one go and send to receiver. 一次性将类对象序列化并发送给接收者。 Receiver deserialize the class object and read the vector array one by one. 接收器反序列化类对象,并一一读取向量数组。

Please let me know which approach is efficient and if any other approach , please guide me. 请让我知道哪种方法有效,如果有其他方法,请指导我。

Also pros and cons of class based data transmission and structure based data transmission and which is suitable for which scenario ? 基于类的数​​据传输和基于结构的数据传输的优缺点,以及哪种情况适合?

Your question lacks some key details, and mixes different concerns, frustrating any attempt to provide a good answer. 您的问题缺少一些关键细节,并且混杂了不同的关注点,使您无法提供一个很好的答案。

Specifically, Method 2 mysteriously "serialises" and "deserialises" the object and contained vector without specifying any details of how that's being done. 具体来说,方法2神秘地“序列化”和“反序列化”对象和包含的向量,而没有指定如何完成操作的任何细节。 In practice, the details are of the kind alluded to in Method 1. So, 1 and 2 aren't alternatives unless you're choosing between using a serialisation library and doing it from scratch (in which case I'd say use the library as you're new to this and the library's more likely to get it right). 实际上,细节是方法1中提到的那种。因此,除非您在使用序列化库和从头做起之间进行选择(在这种情况下,我会说使用库),否则1和2并不是替代方案。因为您是新手,而图书馆更可能会正确解决此问题)。

What I can say: 我可以说:

  • at a TCP level, it's most efficient to read into a decent sized block (given I tend to work on PC/server hardware, I'd just use 64k though smaller may be enough to get the same kind of throughput) and have each read() or recv() read as much data from the socket as possible 在TCP级别,读取一个体面大小的块是最有效的(假设我倾向于在PC /服务器硬件上工作,我只使用64k,尽管较小的块可能足以获得相同的吞吐量),并且每次read()recv()从套接字读取尽可能多的数据
    • after reading enough bytes (in however many read/recvs) to attempt some interpretation of the data, it's necessary to recognise the end of particular parts of the serialised input: sometimes that's implicit in the data type involved, other times it's communicated using some sentinel (eg a linefeed or NUL), and other times there can be a prefixed fixed-size "expect N bytes" header. 在读取了足够的字节(以许多读取/接收次数为单位)以尝试对数据进行某种解释之后,有必要认识到序列化输入的特定部分的结尾:有时在所涉及的数据类型中是隐式的,有时它是使用某些前哨进行通信的(例如换行或NUL),有时可能会有一个固定大小的前缀“ expect N bytes”标头。 This aspect/consideration often applies hierarchically to the stream of objects and nested sub objects etc.. 此方面/考虑因素通常分层应用于对象流和嵌套的子对象等。
    • the TCP read/recvs may deliver more data than were sent in any single request, so you may have 1 or more bytes that are logically part of the subsequent but incomplete logical message at the end of the block assembled above TCP读/接收可能传递的数据比任何单个请求中发送的数据都要多,因此,在上面汇编的块的末尾,您可能具有一个或多个字节,这些字节在逻辑上属于后续但不完整的逻辑消息的一部分
    • the process of reading larger blocks then accessing various fixed and variable sized elements inside the buffers is already supported by C++ iostreams, but you can roll your own if you want C ++ iostream已支持读取较大的块然后访问缓冲区中各种固定和可变大小的元素的过程,但是如果需要,可以自行滚动

So, let me emphasise this: do NOT assume you will receive any more than 1 byte from any given read of the socket: if you have say a 20 byte header you should loop reading until you hit either an error or have assembled all 20 bytes. 因此,让我强调一下:不要假设您从套接字的任何给定读取中接收到的字节数都不会超过1个字节:如果您说20字节的标头,则应该循环读取,直到遇到错误或汇编所有20个字节为止。 Sending 20 bytes in a single write() or send() does not mean the 20 bytes will be presented to a single read() / recv() . 在单个write()send()中发送20个字节并不意味着将20个字节呈现给单个read() / recv() TCP is a byte stream protocol, and you have to take arbitrary numbers of bytes as and when they're provided, waiting until you have enough data to interpret it. TCP是字节流协议,在提供字节数时,您必须获取任意数量的字节,直到有足够的数据来解释它为止。 Similarly, be prepared to get more data than the client could write in a single write() /`send(). 同样,准备获得比客户端在单个write() /`send()中写入的数据更多的数据。

Also pros and cons of class based data transmission and structure based data transmission and which is suitable for which scenario ? 基于类的数​​据传输和基于结构的数据传输的优缺点,以及哪种情况适合?

These terms are completely bogus. 这些术语完全是伪造的。 classes and structures are almost identical things in C++ - mechanisms for grouping data and related functions (they differ only in how they - by default - expose the base classes and data members to client code). 类和结构在C ++中几乎是相同的-分组数据和相关函数的机制(它们的区别仅在于它们-默认情况下-将基类和数据成员暴露给客户端代码的方式)。 Either can have or not have member functions or support code that helps serialise and deserialise the data. 可以具有成员函数或支持代码,以帮助序列化和反序列化数据。 For example, the simplest and most typical support are operator<< and/or operator>> streaming functions. 例如,最简单和最典型的支持是operator<<和/或operator>>流功能。

If you want to contrast these kind of streaming functions with an ad-hoc "write a binary block, read a binary block" approach (perhaps from thinking of structs as being POD without support code), then I'd say prefer streaming functions where possible, starting with streaming to human-readable representations as they'll make your system easier and quicker to develop, debug and support. 如果您想通过专门的“编写二进制块,读取二进制块”的方法(例如,将结构视为没有支持代码的POD)来对比这些流函数,那么我想说一下流函数从流式传输到人类可读的表示形式开始,这将使您的系统更容易,更快捷地进行开发,调试和支持。 Once you're really comfortable with that, if the runtime performance requires it then optimise with a binary representation. 一旦您真正满意了,如果运行时性能需要它,则可以使用二进制表示形式进行优化。 If you write the serialisation code well, you won't notice much difference in performance between a cruder void*/#bytes model of data and proper per-member serialisation, but the latter can more easily support unusual cases - portability across systems with different size ints/longs etc., different byte ordering, intentional choices re shallow vs. deep copying of pointed to data etc.... 如果您很好地编写了序列化代码,您将不会注意到较粗的void*/#bytes数据模型与正确的按成员序列化之间的性能差异,但是后者可以更轻松地支持异常情况-跨不同系统的可移植性大小int / longs等,不同的字节顺序,有意的选择是浅层还是深层复制指向的数据等....

I'd also recommend looking at the boost serialisation library. 我还建议您查看boost序列化库。 Even if you don't use it, it should give you a better understanding of how this kind of thing is reasonably implemented in C++. 即使您不使用它,它也应该使您更好地了解如何在C ++中合理地实现这种事情。

Both methods are equivalent. 两种方法是等效的。 In both you must send a header with message size and identifier in order to deserialize. 在两者中,您都必须发送带有消息大小和标识符的标头,以便反序列化。 If you assume that first option is composed by a serialized 'class' like a normal message, you must implement the same 'code'. 如果您认为第一个选项是由序列化的“类”组成的,就像普通消息一样,则必须实现相同的“代码”。

Another thing you must have in mind is message's size in order to full TCP buffers to optimize communications. 您必须牢记的另一件事是消息的大小,以便使用完整的TCP缓冲区来优化通信。 If your 1st method messages are so little, try to improve the communication ratio with bigger messages like in 2nd option you describe. 如果您的第一种方法消息太少,请尝试使用较大的消息(如您​​描述的第二种方法)来提高通信比率。

Keep in mind that it's not safe simply streaming out a struct or class directly by interpreting it as a sequence of bytes, even if it's a simple POD - there's issues like endianness (which is unlikely to be a real-world problem for most of us), and structure alignment/padding (which is a potential problem). 请记住,这不是安全简单地直接将其解释为一个字节序列,即使它是一个简单的POD流出来了一个结构或类-有没有像排列顺序问题(这是不太可能对我们大多数人的现实世界中的问题),以及结构对齐/填充(这一个潜在的问题)。

C++ doesn't have any built-in serialization/deserialization, you'll either have to roll your own or take a look at things like boost Serialization , or Google's protobuf . C ++没有内置的序列化/反序列化功能,您必须自己动手或看一下boost序列化或Google的protobuf之类的东西

If it is not a homework or study project, there may be little point in fiddling with IPC at TCP stream level especially if that's not something one is familiar with. 如果这不是一项家庭作业或学习项目,那么在TCP流级别上摆弄IPC可能毫无意义,特别是如果这不是人们所不熟悉的。

Use a messaging library, like ØMQ to send and receive complete messages rather than streams of bytes. 使用消息传递库(例如ØMQ)发送和接收完整的消息,而不是字节流。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM