首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++工控机通信

C++工控机通信
EN

Stack Overflow用户
提问于 2012-02-22 06:40:36
回答 4查看 1.4K关注 0票数 1

我正处于困境中,要就以下情况作出决定。敬请专家帮助。

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

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

Communication Method2 :将所有消息放置在向量中,向量将驻留在类对象中。一次序列化类对象并发送到接收方。接收器反序列化类对象并逐个读取向量数组。

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

另外,基于类的数据传输和基于结构的数据传输的优缺点以及哪种情况适合?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-02-22 07:28:01

你的问题缺乏一些关键的细节,并混合了不同的关注,挫败了任何提供一个好答案的尝试。

具体来说,方法2神秘地“序列化”和“反序列化”了对象和包含的向量,而没有具体说明是如何实现的。在实践中,细节就像方法1中提到的那样。因此,除非您在使用序列化库和从头开始使用序列化库之间做出选择(在这种情况下,我会说使用库是新手,而且库更有可能正确),否则,1和2是不可替代的。

我能说的是:

  • 在TCP级别上,将数据读入适当大小的块是最有效的(考虑到我倾向于在PC/服务器硬件上工作,我只需使用64k,虽然较小的容量可能足以获得相同的吞吐量),并让每个read()recv()从套接字中读取尽可能多的数据( )
    • 在读取了足够多的字节(在许多读/recv中)以尝试对数据进行某种解释之后,有必要识别序列化输入的特定部分的结束:有时这是隐含在所涉及的数据类型中的,而另一些时候则是使用某个哨兵(例如,linefeed或NUL)进行通信,而另一些时候则可能有一个前缀固定大小的"expect N字节“头。这个方面/考虑因素通常分层地应用于对象流和嵌套子对象等。
    • TCP读取/recv可能会传递比在任何单个请求中发送的数据更多的数据,因此您可能有一个或多个字节,这些字节逻辑上属于上面组装的块末尾的后续但不完整的逻辑消息的一部分。
    • 读取较大块然后访问缓冲区中各种固定大小的元素的过程已经被C++ iostreams支持,但是如果您愿意,您可以自己滚动。

因此,让我强调这一点:不要假设从给定的套接字读取中接收到的字节超过1字节:如果您有一个20字节的头,您应该循环读取,直到您遇到错误或组装了所有的20个字节。在单个write()send()中发送20个字节并不意味着这20个字节将呈现给单个read() / recv()。TCP是一种字节流协议,当它们被提供时,您必须接受任意数量的字节,直到您有足够的数据来解释它。同样,准备获取比客户机在单个write()/`send()中编写的数据更多的数据。

另外,基于类的数据传输和基于结构的数据传输的优缺点以及哪种情况适合?

这些条款完全是假的。类和结构在C++中几乎是相同的--用于分组数据和相关函数的机制(它们仅在默认情况下--向客户端代码公开基类和数据成员的方式上有所不同)。无论是否有成员函数或支持代码,都可以帮助序列化和反序列化数据。例如,最简单和最典型的支持是operator<<和/或operator>>流函数。

如果您想将这类流函数与一种特殊的“编写二进制块,读取二进制块”的方法进行比较(也许是因为认为结构是POD而没有支持代码),那么我想说的是,如果可能的话,更喜欢流函数,从流到人类可读的表示开始,因为它们将使您的系统更容易开发、更快地调试和支持。一旦您对此感到满意,如果运行时性能需要它,那么使用二进制表示进行优化。如果您很好地编写了序列化代码,您将不会注意到更普通的void*/#bytes数据模型和正确的每个成员序列化之间在性能上的差别,但是后者可以更容易地支持不寻常的情况--跨不同大小的in /long等系统的可移植性,不同的字节排序,有意的选择,对于指向数据的简单复制和深度复制等等.

我还建议查看boost序列化库。即使您不使用它,它也会让您更好地理解这类事情是如何在C++中合理实现的。

票数 5
EN

Stack Overflow用户

发布于 2012-02-22 07:26:29

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

您必须记住的另一件事是消息的大小,以便充分利用TCP缓冲区来优化通信。如果你的第一条方法信息如此之少,试着用更大的信息来提高沟通率,比如在你描述的第二个选项中。

票数 0
EN

Stack Overflow用户

发布于 2012-02-22 08:08:03

请记住,直接将结构或类解释为字节序列并不是安全的,即使它是一个简单的POD --存在诸如endianness (对大多数人来说不太可能成为现实世界的问题)、结构对齐/填充(这是一个潜在的问题)等问题。

C++没有任何内置的序列化/反序列化,您要么必须自己滚动,要么查看一下诸如推进系列化或谷歌的原生质之类的东西。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9390227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档