如何解决在套接字上以正确的填充和字节序发送结构
|| 我定义了几种结构,可以通过不同的操作系统(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位整数转换为网络字节顺序,反之亦然。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。