(C ++ / winsock)包装替代结构

时间:2012-06-05 11:39:07

标签: c++ winsock packet

我一直使用结构来打包和接收数据包,我会通过将它们转换为从主数据包类继承的类来获得任何东西吗?是否还有另一种“c ++ ish”方式用于打包和任何性能提升?

2 个答案:

答案 0 :(得分:1)

这是非常通用的,可能有各种解决方案。这与序列化主题有关,你所说的是一个简单的序列化模型,其中数据包包含可以直接加载到内存中的结构,反之亦然。我认为C和C ++在这种情况下非常棒,因为它们允许您直接编写类似struct的内容来流式传输并轻松地将其读回。在其他语言中,您可以实现字节对齐,或者您应该序列化对象以便能够将它们写入流。

在某些情况下,您需要读取XML,SOAP等字符串流。在某些应用程序中,您应该使用结构。在某些情况下,您需要将对象序列化为流。这取决于。但我认为使用结构和指针比使用对象序列化更具前瞻性。

在您的情况下,我认为每个实体都有2个结构。一个沿着wire或file移动的结构,以及一个将实体实例保存在内存中的类。如果对对象使用二进制序列化,则只需使用一个类来发送,接收和保留实例。

答案 1 :(得分:1)

数据建模

通常,您的C ++类应该考虑它们建模的数据中的冗余。因此,如果数据包共享一些共同的布局,那么您可以创建一个类来模拟该数据及其上的操作。您可能会发现派生类添加反映可能的数据包数据布局层次结构的其他数据成员很方便,但有时可能同样方便的是让不相关的类反映数据包部分的不同布局(特别是如果长度或顺序部分信息可能会有所不同。)

为了给出一个更简单的案例更合适的例子 - 如果你有一个标准的包头,包含一个记录id,记录大小,以字节为单位和序列id,你可以合理地把这些字段放到一个类中,公开为每个不同的记录id派生一个类。基类可能具有成员函数,用于在从网络字节顺序转换为本地字节顺序时读取这些值,检查序列ID是否根据需要递增等等 - 所有派生类及其用户都可以访问它们。

运行时多态性

您应该对虚拟成员保持警惕 - 在几乎所有实现中,它们都会在对象中引入虚拟分派指针,这可能会阻止它们镜像网络数据包中的数据布局。如果有理由想要运行时多态(并且很容易,特别是在读取数据包时),您可能会发现有一个类的多态层次结构与非多态数据布局的层次结构具有1:1的对应性很有用。类,只包含指向内存中数据位置的指针。

效果

使用具有故意镜像网络数据包的布局的类或结构可能允许您就地操作该内存并且非常方便,相信编译器可以创建有效的代码来执行此操作。编译器通常都很擅长。

该访问的效率(速度)应完全不受影响由用于建模数据的类的层次结构。所涉及的数据偏移和对非虚函数的调用都将在编译时解决。

如果引入虚函数,可能会看到性能降级,因为它们可能会阻止内联并需要额外的指针间接,但是您应该通过考虑在布局特定操作之间切换的方式和频率来将其置于上下文中你需要支持(例如,在所有地方使用switch (record_id)if (record_id == X)或显式函数指针。)