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

我已经尝试过弄乱语法,但是我不知道为什么它会出现段错误。我认为这与我必须为文件中的位置重置指针有关,但是我没有任何线索。

该函数的调用方式如下:

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


任何帮助将不胜感激!

最佳答案

__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];


这将以小尾数格式为您提供错误的ucharbuff值,其中最重要的部分位于更高的内存地址。

关于c - 如何运行fread()以固定大小的块提取数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54729162/

10-11 16:46