如何运行fread()以固定大小的块提取数据

问题描述 投票:0回答:1

我试图从一个文件中读取并通过C中的UDP套接字连接发送它。我相当肯定我正在使用fread(),但是如果我再次尝试使用fread(),我会得到一个段错误。我试图发送超过1kb的数据包,因此,我试图一次从文件中提取1017个字符。

我试过搞乱语法,但我无法弄清楚为什么它是segfaulting。我认为这与我必须重置指针我在文件中的位置有关,但我不知道。

该函数被调用如下:

fread(datapkt.data, datapkt.pktLen, 1, filereq);

datapkt.data已声明

char data[1017]

datapkt.pktLen被定义为1017.我正在尝试读取一个大小为1017的块,而filereq是打开的FILE *

此函数第一次工作,如果我将应用程序限制为仅发送第一个数据包,它将发送1017个字节,没有问题。一旦第二次调用此函数,程序就会出现段错误。我想自动化这个过程,我在UDP上使用一个停止走走的架构,我用数据构建一个结构,将它序列化为一个char缓冲区,然后发送它并反序列化它。一旦获得数据包,客户端就会发送一个ACK,一旦服务器收到ACK,它就会发送下一个1017字节等,直到文件结束。我有一切工作,除了这个fileread()崩溃。这是通过gdb bt为segfault提供的信息:

__memmove_sse2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:370
#1  0x00007ffff7a6f7db in __GI__IO_file_xsgetn (fp=0x555555757670, data=<optimized out>, n=63747) at fileops.c:1318
#2  0x00007ffff7a633c1 in __GI__IO_fread (buf=<optimized out>, size=63747, count=1, fp=0x555555757670)
    at iofread.c:38

任何帮助都非常感谢!

c fread
1个回答
1
投票
__GI__IO_fread (buf=<optimized out>, size=63747, count=1, fp=0x555555757670) at iofread.c:38
                                     ^^^^^^^^^^

这条线很有意思,特别是size的论点是63747。它让我相信你没有用1017这个论点来称呼它。

这是因为你是用一些其他值明确地调用它,还是用一个被你的第一个fread覆盖的变量调用它很难说没有看到更多的代码,但这些是你需要研究的两个最可能的原因。

你应该做的第一件事是,在调用fread之前,实际上输出datapkt.pktLen的当前值以查看是否有什么东西在改变它。

有一点我感兴趣地注意到,你看起来用作第二长度的值是63747249 * 256 + 3。通过惊人的(几乎肯定是非)巧合,将这两个字节反转给出3 * 256 + 249 == 1017或你应该使用的长度。

因此很可能是某些描述的字节序问题,如果您在具有不同字节序的系统之间通过线路发送二进制信息,或者如果您的代码在假设某个字节序的情况下构建值,则通常会发生这种情况,例如:

uint16_t datalen = ucharbuff[0] * 256 + ucharbuff[1];

这将在little-endian格式的ucharbuff上给出错误的值,其中最重要的组件位于更高的内存地址。

© www.soinside.com 2019 - 2024. All rights reserved.