在套接字上发送一个结构,在C中使用正确的填充和字节顺序

Geo*_*Lee 5 c struct tcp padding endianness

我有几个结构被定义为通过不同的操作系统(tcp网络)发送.定义的结构是:

struct Struct1 { uint32_t num; char str[10]; char str2[10];}
struct Struct2 { uint16_t num; char str[10];}   

typedef Struct1 a;
typedef Struct2 b;
Run Code Online (Sandbox Code Playgroud)

数据存储在文本文件中.数据格式如下:

  • 123
  • 馅饼
  • 脆皮

Struct1a存储为3个单独的参数.但是,struct2是两个独立的参数,第二行和第三行都存储在char str []中.问题是当我通过多个网络写入服务器时,数据未正确接收.有许多空间可以分隔结构中的不同参数.当我写入服务器时,如何确保正确的发送和填充?如何正确存储数据(动态缓冲区或固定缓冲区)?

write的例子:write(fd,&a,sizeof(typedef struct a)); 它是否正确?

struct2的问题接收侧输出:

  • 123(,)
  • 0(,馅饼)
  • 0(地壳)

正确的输出

123(馅饼,地壳)

Fre*_*Foo 10

write(fd,&a, sizeof(a));是不正确的; 至少不可移植,因为C编译器可能在元素之间引入填充以确保正确对齐.sizeof(typedef struct a)甚至没有意义.

您应该如何发送数据取决于协议的规格.特别是,协议定义了发送字符串的各种方式.struct分开派遣会员通常最安全; 通过多次调用写入或writev(2).例如,发送

struct { uint32_t a; uint16_t b; } foo;
Run Code Online (Sandbox Code Playgroud)

通过网络,在哪里foo.a并且foo.b已经具有正确的字节顺序,您可以执行以下操作:

struct iovec v[2];
v[0].iov_base = &foo.a;
v[0].iov_len  = sizeof(uint32_t);
v[1].iov_base = &foo.b;
v[1].iov_len  = sizeof(uint16_t);
writev(fp, v, 2);
Run Code Online (Sandbox Code Playgroud)