【问题标题】:How to read and transfer PDF files in C with fread()如何在 C 中使用 fread() 读取和传输 PDF 文件
【发布时间】:2021-12-24 07:24:03
【问题描述】:

我正在用 C 语言编写 TFTP 客户端。到目前为止,我在将文件读入缓冲区(512 B)并将其传输到服务器方面没有问题。但是,我正在努力阅读包含二进制数据的 PDF 等文件。

        size_t nmemb = fread(data_buf, sizeof(char), 512, fp);
        ...
        /* Create DATA packet and send it to TFTP server */ 
        count = sprintf(message, "%c%c%c%c%s", 0, DATA, 0, block_number, data_buf); 
        sendto(sock, message, count, 0, (const struct sockaddr *)&server, sizeof(server));

我通过单独打印每个缓冲区进行了测试:printf("%d: %s\n", nmemb, data_buf); 看起来 nmemb 总是 512,这是正确的,但是 printf() 在到达第一个 NULL 字节时停止打印数据,我确信这代表给定字符串(缓冲区)的结尾。

通过 TFTP 协议发送的 DATA 数据包中的缓冲区数据在第一次出现 NULL 字节时也会被切断 - 我在 Wireshark 中对此进行了测试。

有没有办法通过使用fread() 的替代方法或更改通过套接字发送数据包的方式来解决此问题?感谢您的任何回答。

【问题讨论】:

  • 您似乎已经知道文本和二进制之间存在差异。不要在二进制数据上使用像 snprintf 这样的字符串函数。它只是不会像你发现的那样工作。使用直接内存复制/设置操作。
  • .pdf 文件中的数据可以包含二进制 [不可打印] 字符。而且,其中之一可以是 0x00。因此,您可以使用printf 打印该数据。同样,由于您已经说明的原因,您不能使用sprintf。它在 EOS (0x00) 字符处停止。 sprintf 的问题是为什么它在传输中停止并且wireshark 看不到它。

标签: c sockets pdf fread sendto


【解决方案1】:

您不能为此使用 printf 系列函数,因为它们会在遇到 \0 时停止。

第一种方法:使用memcpy

size_t nmemb = fread(data_buf, 1, sizeof data_buf, fp);

char message[sizeof data_buf + 4]; // presumably

count = sprintf(message, "%c%c%c%c", 0, DATA, 0, block_number);
memcpy(message + count, data_buf, nmemb);

第二种方法(首选方法):避免将fread 直接复制到稍后发送的缓冲区中:

char message[512 + 4] = {0, DATA, 0, block_number};
size_t nmemb = fread(message + 4, 1, 512, fp);
sendto(sock, message, nmemb + 4, 0, (const struct sockaddr *)&server, sizeof(server))

注意:sizeof(char) 始终为 1。不能是其他任何值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多