通过c套接字发送结构

Send struct over c sockets

本文关键字:结构 套接字 通过      更新时间:2023-10-16

我正在构建一个UDP聊天应用程序。在C套接字和另一端memset接收数据上发送C结构是否安全?struct中的所有数据都被memset为空,所以我假设struct的大小总是恒定的。我可能会遇到什么问题?

更有经验的程序员如何处理这个问题?

是的,这是安全的,但我们应该警告首先。如果您在不同的平台之间传递,则可能会遇到问题,然后您需要担心字节排序/打包(在许多其他问题中可能)。话虽如此,如果您不知道如何做到这一点,那么假设您将以与发送相同的顺序可靠地接收struct是不安全的。

无论你怎么做,都要进行单元测试。编译器和平台在这些方面差异很大,所以不要盲目地认为它们是一致的。

编译器可以随心所欲地改变结构对齐方式(例如,出于性能原因)。要求一些限制通常是特定于编译器的,尽管MSVC和gcc(通过扩展)支持这种限制

#pragma pack(push, 1)
struct Foo {
  // ..
};
#pragma pack(pop)

这强制它以1字节的边界对齐,所以没有布尔值。

如果你想完全兼容,那么你自己序列化每个字段。这真的没有那么多的工作。

您还必须处理顺序,正如其他人所提到的。

struct中的所有数据都被memset为空,所以我假设struct的大小总是恒定的。

这没有多大意义。对象总是有固定的大小。"Nullpadding with memset"与此无关。

是安全的发送C结构在C套接字和在另一端memset接收数据?

不,没有。

最好考虑发送"数据",而不是内存中对象的精确的、按字节计算的物理内容。

我可能会遇到什么问题?

  • 成员填充
  • 数据对齐
  • 类型大小
  • 字节顺序
  • 间接本;指向数据而不是数据本身的指针

更有经验的程序员如何处理这个问题?

最好正确序列化。

创建一种数据格式,无论你的应用程序在什么机器上都能识别,并使用它来表示你的聊天数据。

  1. 有时为了提高效率,你必须设计一个二进制格式,并使用聪明的、健壮的技术在目标机器上正确地反序列化信息,考虑到上面列出的考虑因素。

  2. 然而,对于简单的工作,您可以使用人类可读的文本格式。

你必须小心你的结构体不包含指针(像char*字符串)。这也适用于在结构体中存储std::string时,因为std::string在它内部有一个指针。