Как запустить fread () для извлечения данных в чанках фиксированного размера - PullRequest
0 голосов
/ 17 февраля 2019

Я пытаюсь прочитать файл и отправить его по соединению с сокетом UDP в C. Я вполне уверен, что я правильно использую fread (), однако, если я пытаюсь снова использовать fread (), я получаю segfault,Я пытаюсь отправить более 1 КБ пакетов, и поэтому я пытаюсь извлечь из файла 1017 символов за раз.

Я попытался возиться с синтаксисом, однако не могу понять, почему это так.segfaulting.Я предполагаю, что это связано с тем, что мне нужно сбросить указатель на то место, где я нахожусь в файле, но я понятия не имею.

Функция вызывается следующим образом:

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

datapkt.data объявлен

char data[1017]

datapkt.pktLen определен для 1017. Я пытаюсь прочитать один кусок размером 1017, а filereq - это открытый ФАЙЛ *

Эта функция работаетв первый раз, и если я ограничиваю приложение отправкой только первого пакета данных, оно отправляет 1017 байт без проблем.При повторном вызове этой функции программа отключается.Я хотел бы автоматизировать этот процесс, я использую архитектуру stop-and-go поверх UDP, где я строю структуру с данными, сериализую ее в буфер символов, затем отправляю и десериализую.Как только пакет получен, клиент отправляет 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

Любая помощь очень ценится!

1 Ответ

0 голосов
/ 17 февраля 2019
__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 или длину, которую вы должны использовать.

Так что вполне вероятно, что проблема с порядком байтов в некотором описании, что-тоэто часто случается, если вы отправляете двоичную информацию по проводам между системами с различным порядком байтов или если у вас есть код, который создает значения в предположении определенного порядкового номера, например:

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

Тодаст неправильное значение для ucharbuff в формате с прямым порядком байтов, где наиболее значимые компоненты находятся на более высоких адресах памяти.

...