我正在读取结构文件,然后将它们写入服务器。 这是一段代码:
struct b{
uint16_t num;
char str[10];
} x;
struct a{
uint32_t pid;
char str1[10];
char str2[10];
} y;
while(fscanf(fp,"%s",buff) != EOF)
while(1){
c = getchar();
if (c == '\n')
break;
else
buff[i]= c ;
i++;
write(fd, &b,sizeof(b))
文本文件格式
利
如何读取文件并将其存储到每个结构中?
当我写信给服务器时,它看起来像是
写(fd,& a,sizeof(struct a))。 写(fd,& b,sizeof(struct b))? 如何确保正确的填充,字节顺序
这是我运行文件的方式:/a.out IP PORT< file.txt的
答案 0 :(得分:0)
当您说“阅读并将文件存储到每个结构”时,您能澄清一下这个问题吗?
要确保正确的填充和字节序,您必须做两件事:
一次发送一个结构字段。这是一种痛苦。由于您将每个结构成员声明为uint16_t
类型(并且来自该系列),因此sizeof()将在所有平台上为您提供相同的答案。
要确保字节顺序,您必须使用host-to-network-order系列。请参阅:http://www.gnu.org/s/hello/manual/libc/Byte-Order.html
执行此操作时,您必须在发送时使用htons()
(主机网络短路),然后在接收时使用ntohs()
(网络到主机短路)。对于结构的每个成员。
人们常常忽视这一点;如果这两台机器都是现代的英特尔机箱,这对我们绝大多数人来说都是如此,那么你可以放弃发送结构的代码。但就像你提到的那样,这并不是保证填充和终结!
您还可以使用#pragma pack() GNU指令来指定如何处理填充。如果您可以依赖于客户端和服务器的GNU工具链,那么这是有效的,因为它不是C规范的一部分。
答案 1 :(得分:0)
不要对结构使用send / recv(套接字)或读/写(文件描述符)。它几乎可以保证在以后打破。在其他问题中,结构成员的填充和/或对齐可能会根据编译器,编译选项和环境而改变。
相反,将数据编组为独立格式(如文本)并发送。如果双方的数据必须完全相同,则将其编码为base 64并预先设置校验和。
如果绝对必须传输二进制数据,请记住将每个结构成员转换为网络字节顺序(man byteorder
)并单独发送每个数据。