2012-02-22 141 views
1

我在困境中对下面的场景做出决定。请需要专家的帮助。C++ IPC通信

场景:在两个框中运行的两个进程之间存在TCP/IP通信。

通信方法1:基于流的套接字通信。在接收端,他将接收整个字节缓冲区,并将头几个固定字节解释为头并对其进行去序列化,并了解消息长度并开始获取该长度的消息,并对其进行反序列化,然后继续处理下一个消息头on ...

通信方法2:将所有消息放在一个向量中,向量将驻留在一个类对象中。一次序列化类对象并发送给接收者。接收器反序列化类对象并逐个读取矢量数组。

请让我知道哪种方法是有效的,如果有其他方法,请指导我。

还有基于类的数​​据传输和基于结构的数据传输的优缺点,哪个适合哪种场景?

+0

我没有看到两种方法之间的区别。对于第二种方法,发送方必须序列化向量,将其发送给接收方(可能通过流套接字),并且接收方将接收到的数据反序列化为向量。这与第一种方法有何不同? – 2012-02-22 07:07:02

+0

我的意思是这里是1.单字节缓冲区包含10个结构序列化并发送到客户端。 2.单字节缓冲区包含一个拥有10个结构的对象。并序列化一个对象并发送给客户端。如果我们这样做,在接收端,一个反序列化就足够了。在方法(1)中,我们有反序列化次数。你明白了吗? – Muthu 2012-02-22 07:16:21

+0

案例2中的持有对象中的向量仍然需要序列化/反序列化。 – 2012-02-22 07:20:43

回答

4

您的问题缺乏一些关键细节,并混合了不同的担忧,挫败任何提供良好答案的企图。

具体而言,方法2神秘地“串行化”和“反序列化”对象和包含的向量,而没有指定如何完成的任何细节。实际上,细节是在方法1中提到的那种。所以,1和2不是替代方案,除非你选择使用序列化库并从头开始(在这种情况下,我会说使用库因为你是新手,图书馆更有可能做到这一点)。

我能说什么:

  • 在TCP水平,这是最有效的读入一个体面的大小的块(因为我倾向于在PC /服务器硬件的工作,我只是用64K虽然较小可能足以获得相同类型的吞吐量)并且每个read()recv()从套接字读取尽可能多的数据
    • 在读取足够的字节(然而在很多读/ recvs中)以试图对数据进行一些解释之后,有必要识别序列化输入的特定部分的结尾:有时这在涉及的数据类型中是隐含的,其他时间使用一些哨点(例如,一个换行符或NUL),其他时间可以有一个前缀固定大小的“期望N字节”头。这方面/考虑通常分层次地应用于对象流和嵌套子对象等。
    • 读/ RECVS可以比任何单个请求被送到传送更多的数据,因此可能有1首或更多个字节,其在逻辑上是在该块的上述
    • 组装结束时的随后的但不完全的逻辑消息的一部分的TCP读大的块,然后访问该缓冲区内的各种固定和可变大小的元素的过程中已经被C++输入输出流的支持,但你可以滚你自己,如果你想

所以,我要强调这一点:做不要假设你会从任何给定的套接字读取中接收到超过1个字节:如果你有一个20字节的头文件,你应该使用它直到你遇到错误或者汇编了所有20个字节。在单个write()send()中发送20个字节并不意味着20个字节将呈现给单个read()/recv()。 TCP是一种字节流协议,您必须在提供任意数量的字节时,等待您有足够的数据解释它。同样,准备获得比客户可以在单个发送(*)中写入更多的数据。

还有基于类的数​​据传输和基于结构的数据传输的优缺点,哪个适合哪种场景?

这些术语完全是假的。类和结构在C++中几乎是完全相同的 - 用于对数据和相关函数进行分组的机制(它们仅在默认情况下将基类和数据成员公开给客户端代码的方式不同)。可以有或没有成员函数或支持代码来帮助序列化和反序列化数据。例如,最简单和最典型的支持是operator<<和/或operator>>流式传输功能。

如果你想将这些类型的流式函数与特定的“编写二进制块,读取二进制块”方法进行对比(可能是因为没有支持代码将PTS视为POD),那么我会说在可能的情况下更喜欢流式传输功能,从流式传输到人类可读的表示,因为它们会使您的系统更易于开发,调试和支持。一旦你真的对此感到满意,如果运行时性能需要它然后用二进制表示进行优化。如果你写好序列化代码,你不会注意到一个粗糙的void*/#bytes数据模型和正确的per-member序列化之间的性能差别,但后者可以更容易地支持异常情况 - 跨不同大小ints/longs的系统之间的可移植性等等,不同的字节顺序,故意选择重浅层与深层复制指向数据等等。我还建议看看boost序列化库。即使你不使用它,它应该让你更好地理解这种事情是如何在C++中合理实现的。

0

两种方法都是等价的。在这两种情况下,您都必须发送一个包含消息大小和标识符的头文件以反序列化。如果你假定第一个选项是由像普通消息那样的序列化“类”组成的,那么你必须实现相同的“代码”。

你必须记住的另一件事是消息的大小,以便完整的TCP缓冲区来优化通信。如果您的第一个方法消息太少,请尝试使用更大的消息来提高通信比率,例如您在第二个选项中描述的消息。

0

请记住,这是安全简单地流了出来,结构或类直接将其解释为一个字节序列,即使它是一个简单的POD - 有没有像排列顺序问题(这是不太可能是现实对于我们大多数人来说这是世界性的问题),以及结构对齐/填充(其中是一个潜在的问题)。

C++没有任何内置的序列化/反序列化,你必须自己推出或看一下像boost Serialization或谷歌的protobuf

0

如果这不是一个家庭作业或学习项目,那么在TCP流级别处理IPC可能没什么意义,特别是如果这不是人们所熟悉的。

使用消息传递库,如ØMQ发送和接收完整的消息而不是字节流。