c - 将结构写入管道的正确方法是什么

标签 c linux

<分区>

在 linux 2.6.x 上,给定以下结构

struct A
{
  int a;
  int b;
} ss;

我想到将上述结构写入管道的两个选项是

  1. 从 &ss 到 sizeof(ss) 的 memcpy
  2. 复制 ss->a,然后复制 ss->b

一个比另一个好吗?

最佳答案

没有“正确”的方法,但有些方法肯定比其他方法好。

对于初学者来说,int 的大小取决于机器、编译器和选项。您可能不希望您的网络/IPC 协议(protocol)随这些而变化。其次,整数中字节的顺序可以随着相同的事物而变化。因此,首先定义整数的大小和顺序(字节顺序)。假设您使用 32 位,大字节序。然后使用数字/逻辑操作提取这些字节 - 而不是字节复制或覆​​盖。最后,您可能想要在流中实际编码您的大小假设。

一些示例代码。每个函数将参数编码到提供的缓冲区中,并返回缓冲区中使用的字符数。

int encode_int(int v, unsigned char *s) {
   s[0] = (v>>24) & 0xff;
   s[1] = (v>>16) & 0xff;
   s[2] = (v>>8) & 0xff;
   s[3] = v & 0xff;
   return 4;
}
int encode_A(struct A *a, unsigned char *s) {
   int offset = 0;
   s[offset++] = 4; // Size of ints - really belongs in a global header or in encode_int
   offset += encode_int(a->a, s+offset);
   offset += encode_int(a->b, s+offset);
   return offset;
}

解码必须获取提供的字节并使用逻辑/算术运算重新组合整数。如果您希望主要是小整数和/或还想处理 64 位平台,另一种可能性是使 encode_int 使用可变数量的字节(并对它使用的字节数进行编码)。还有许多其他选项 - 最主要的是不要让内存中表示的任意性来定义您的协议(protocol)。

另请查看 ntohl、htonl、ntohs、htons 标准函数。

附言。最后一次编辑 - 如果读取器中的整数大小与编写器中的整数大小不同,则必须注意正确处理负整数。

关于c - 将结构写入管道的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13906753/

相关文章:

c - 为什么 sem_timedwait() 没有醒来?

c++ - linux C++ : libaio. h 不包含 io_context _t 的定义?

java - linux/mac下用eclipse查询tomcat

linux - 当密码有时从 github 克隆!在里面

c - 从 ext3 linux 安全删除文件

c - 尝试将变量分配为 C 中数组的长度

java - JAVA的引用和C、C++的引用有区别吗?

c - Makefile:将多个c文件制作成多个二进制文件

linux - 如何使用 grep 在一个字段上搜索子字符串?

linux - 如何从时间戳而不是当前时间中减去 10 分钟