2011-08-25 105 views
4

我正在构建一个UDP聊天应用程序。它安全地通过c套接字发送C结构,并在另一端memset接收数据? struct中的所有数据都与memset无效,所以我假设结构的大小始终为常量。我可能遇到什么问题?通过c socket发送结构

更有经验的程序员如何接近这个?

+0

考虑寻找协议缓冲区http://code.google.com/p/protobuf/ – Jack

回答

6

是的,它是安全的,但我们应该警告这个第一。你可能遇到问题如果你在不同的平台之间传递它,然后你需要担心字节排序/打包(之间的其他一些问题可能)。话虽如此,如果你不知道如何做到这一点,那么假设你可以按照你发送的顺序可靠地收到struct是不安全的。

+3

这可能是一个非常严重的问题! –

+0

我相信PPC和MIPS是两个不同字节顺序的平台。您通常可以在游戏系统和网络设备(如WiFi路由器)中找到这些芯片。 –

+0

不同的包装很容易找到:32位和64位系统通常会以不同方式包装整数。 –

1

你必须要小心,你的结构不包含指针(如char*字符串)。当您在结构中存储std::string时也适用,因为std::string中有一个指针。

5

但是你这样做,单元测试地狱出来。编译器和平台在这些方面差异很大,所以千万不要盲目认为它是一致的。

编译器可以在它们的随心所欲改变结构对准(出于性能原因,例如)。询问一些限制一般都是具体的编译器,虽然这是一个由MSVC和gcc(通过扩展),支持

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

这迫使它在1个字节边界对齐,所以没有布尔值。

如果你想成为完全兼容,然后自己序列化的每个字段。这真的不是所有的工作。

您还必须处理字节排列顺序,如其他人所说。

+0

在新的C++ 11标准,这个'#pragma pack'扩展将不再需要,因为我们有'alignas'说明符:) –

+0

这真是个好消息。我一直在支持下发现很多这类东西。 –

+0

是的,但你必须等待一段时间。尽管编译器已经实现了很多大的C++ 11特性,但是我没有知道的编译器实现了'alignas'但是:( –

3

struct中的所有数据都是memset与memset,所以我假设结构的大小始终是常量。

这并没有什么意义。对象总是有一个固定的大小。 “使用memset无纸化”与它无关。

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

不,不是真的。

更好地考虑发送“数据”而不是内存中对象的确切字节方式的物理内容。

我可能遇到什么问题?

  • 会员填充
  • 数据对齐
  • 类型大小
  • 字节序
  • 的间接—指针数据,而不是数据本身

如何更有经验的程序员approachi这个?

最好做好序列化。

创建一个数据格式,您的应用程序无论在哪台机器上都能识别,并用它来表示您的聊天数据。

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

  2. 但是,对于简单的工作,您可以使用人类可读的文本格式。不能真的出问题了。

+1

@Downvoter:习惯性地解释你自己。 –

+0

+1我认为这是一个很好的答案,因为它清楚地解释了所有问题。 OTOH,如果你小心并且有一个计划来处理你可能遇到的每个问题,我会认为C被设计为允许这样的事情如果你知道如何正确地做到这一点。 –

+0

@Ken:我不认为C是,但是遵循其任务的一些实现可能是。 –