我目前有一个基本的客户端/服务器设置。服务器需要从客户端获取请求并需要响应不同的请求消息类型。客户端请求的一个例子可能是获取可用文件列表,还有多少其他客户端连接到服务器等。这在C/C++套接字通信中是否合理?
我显然必须找出一种方法来确定从接收到的消息中的消息类型发件人。我想知道,如果我有一个用必要数据定义的结构,那么我是否可以将结构强制转换为void *,通过发送(sockfd,message,length,flags)系统调用,并在接收端进行发送回到结构。这当然假定我在同一个环境中运行客户端和服务器。
举例来说,如果我有以下结构:
struct message {
enum messageType { GET_FILES, GET_CLINET_NUMBER} messageType,
}
,并使用该结构以如下方式
struct message msg;
msg.messageType = GET_FILES;
send(server_sockfd, (void*)&msg, sizeof(struct), 0)
,并在接收器上发送消息,
recv(,msg_buffer);
struct message received = (struct message*)msg_buffer;
忽略这些小的语法问题,任何人都可以建议这个方案是否可行?如果没有,是否有任何其他方式来传递消息而不发送原始char *?
另一个,甚至可能更糟的问题:填充字节。 C++编译器有时会在结构的成员之间添加'不可见'填充字节,以便为目标CPU提高内存访问效率。填充不是标准化的,所以它可以在一个编译器和另一个编译器之间,或者在同一个编译器的两个版本之间,甚至在来自同一个编译器版本的构建之间(特别是如果它们使用不同的优化级别构建时)不同地完成。因此,除非连接的两端都运行完全相同的可执行二进制文件,否则事情可能会中断。 – 2011-06-05 18:35:48
对齐在给定的ISA ABI上是标准化的,并且在任何实字机器上,填充是对齐所需的最小值。而且,对于真实世界机器上的几乎所有类型,对齐都是类型的大小。对齐必须总是*均匀地分割*类型的大小(由于C数组表示语义),所以如果设计的结构是这样的,那么在没有填充的情况下,每个元素将以其大小的倍数开始,那么你可以基本确定没有填充。 – 2011-06-05 18:52:55