如何 运行 fread() 以固定大小的块提取数据
How to run fread() to extract data in fixed-size chunks
我正在尝试从文件中读取并通过 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 上使用走走停停的架构,我在其中构建一个包含数据的结构,将其序列化为一个字符缓冲区,然后将其发送并反序列化。获取数据包后,客户端发送 ACK,一旦服务器收到 ACK,它就会发送下一个 1017 字节,依此类推,直到文件结束。除了这个 fileread() 崩溃之外,我一切正常。这是通过 gdb bt 为段错误提供的信息:
__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
看看是否有什么东西正在改变它。
不过我感兴趣地注意到一件事,您似乎用作第二个长度的值是 63747
或 249 * 256 + 3
。通过一个惊人的(几乎肯定不是)巧合,反转这两个字节得到 3 * 256 + 249 == 1017
或你 应该 使用的长度。
很可能是某些描述的端序问题,如果您在具有不同端序的系统之间通过线路发送二进制信息,或者如果您的代码假定某个端序来构建值,则经常会发生这种情况-ness,例如:
uint16_t datalen = ucharbuff[0] * 256 + ucharbuff[1];
这会在小端格式的 ucharbuff
上给出错误的值,其中最重要的组件位于 更高的 内存地址。
我正在尝试从文件中读取并通过 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 上使用走走停停的架构,我在其中构建一个包含数据的结构,将其序列化为一个字符缓冲区,然后将其发送并反序列化。获取数据包后,客户端发送 ACK,一旦服务器收到 ACK,它就会发送下一个 1017 字节,依此类推,直到文件结束。除了这个 fileread() 崩溃之外,我一切正常。这是通过 gdb bt 为段错误提供的信息:
__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
看看是否有什么东西正在改变它。
不过我感兴趣地注意到一件事,您似乎用作第二个长度的值是 63747
或 249 * 256 + 3
。通过一个惊人的(几乎肯定不是)巧合,反转这两个字节得到 3 * 256 + 249 == 1017
或你 应该 使用的长度。
很可能是某些描述的端序问题,如果您在具有不同端序的系统之间通过线路发送二进制信息,或者如果您的代码假定某个端序来构建值,则经常会发生这种情况-ness,例如:
uint16_t datalen = ucharbuff[0] * 256 + ucharbuff[1];
这会在小端格式的 ucharbuff
上给出错误的值,其中最重要的组件位于 更高的 内存地址。