在套接字上以正确的填充和字节序发送结构

|| 我定义了几种结构,可以通过不同的操作系统(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;
数据存储在文本文件中。 数据格式如下: 123 馅饼 脆皮 Struct1 a存储为3个单独的参数。但是,struct2是两个单独的参数,第二行和第三行都存储到char str []中。问题是,当我通过多个网络写入服务器时,无法正确接收数据。有许多空格将结构中的不同参数分开。写入服务器时如何确保正确的发送和填充?如何正确存储数据(动态缓冲区或固定缓冲区)? 写的例子:write(fd,&a,sizeof(typedef struct a));它是否正确? struct2的问题接收端输出: 123(,) 0(,派) 0(外壳) 正确的输出 123(饼皮)     
已邀请:
write(fd,&a, sizeof(a));
不正确;至少不能移植,因为C编译器可能会在元素之间引入填充以确保正确对齐。
sizeof(typedef struct a)
甚至没有意义。 您应该如何发送数据取决于协议的规范。特别是,协议定义了各种各样的发送字符串的方式。通常,单独发送
struct
成员最安全;通过多次通话或or4ѭ。例如,发送
struct { uint32_t a; uint16_t b; } foo;
通过网络,其中
foo.a
和correct7ѭ已经具有正确的字节序,您将执行以下操作:
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);
    
通过网络发送结构非常棘手。您可能遇到以下问题 字节尾数与整数有关。 编译器引入的填充。 字符串解析(即检测字符串边界)。 如果性能不是您的目标,我建议为要发送和接收的每个结构(ASN.1,XML或自定义)创建编码器和解码器。如果确实需要性能,您仍然可以使用结构并通过固定字节序(即网络字节)来求解(1) 顺序),并确保您的整数按原样存储在这些结构中;以及(2)通过修复编译器并使用编译指示或属性来强制执行“ packed”结构。 例如,Gcc使用attribute((packed))如下:
struct mystruct {
  uint32_t  a;
  uint16_t b;
  unsigned char text[24];
} __attribute__((__packed__));
(3)不容易解决。在网络协议上使用以null结尾的字符串 并根据它们的存在使您的代码容易受到多种攻击。如果需要使用字符串,我将使用适当的编码方法,例如上面建议的方法。     
一种简单的方法是为每个结构编写两个函数:一个将文本表示转换为结构,另一个将结构转换回文本。然后,您只需通过网络发送文本,然后在接收方将其转换为您的结构。这样,字节序并不重要。     
有转换功能可确保二进制整数在网络中的可移植性。使用htons,htonl,ntohs和ntohl将主机的16位和32位整数转换为网络字节顺序,反之亦然。     

要回复问题请先登录注册