【问题标题】:C HTTP Client Receive .PNG FileC HTTP 客户端接收 .PNG 文件
【发布时间】:2020-12-26 03:44:15
【问题描述】:

所以我正在用 C 编写这个简单的 HTTP 客户端,而且,我不太了解 C。这是它的要点。我让 HTTP 客户端正常工作,我可以发送 GET 请求和返回响应。我什至可以解析 HTTP 标头以获取我想要的信息(尽管我的解决方案是不雅的)。问题是当它是二进制信息时,比如图片文件。我敢肯定这很简单,但是……这是我所拥有的精简版。

FILE *fp = fopen("output", "wb"); // Open the file for writing
while (recv(s, buf, MAXDATASIZE - 1, 0) > 0) { //This just iterates over our HTTP response, it works don't worry
    if (is_text == 1) { // Assume I already parsed the headers and know the Content-type
        fprintf(fp, "%s", buf); // This works, it just writes the text to our output file
    }
    else { // Anything not text, this is where the problem is
        fwrite(buf, sizeof buf, 1, fp); // <-- **This is the problem line**
    }
    memset(buf, 0, MAXADATASIZE -1, 0); // Reset the buffer, for the next iteration
}
flose(fp); // Close the file

所以,我标记为问题行的行确实将一些二进制内容写入我的输出文件,它只是永远不会与原始文件匹配。它们不仅不同,它们的大小也相差一百个数量级。只是不是同一个文件。是的,我知道需要找出一种方法来去除标题,否则文件总是会有所不同,但显然这还不是问题所在。

-- 额外信息:
Ubuntu 18.04.5
gcc 版本 7.5.0
“硬件”是一个 64 位的虚拟机虚拟机

【问题讨论】:

  • 您应该检查fopen 的返回值以确保文件正确打开。 recv 返回读入buf 的字节数,这很重要。 memset 需要 3 个参数,而不是 4 个,这甚至是如何编译的? (无论如何,每次迭代后memsetting buf 没有意义,只需检查recv 的返回值即可查看写入了多少字节)。
  • 是的,这是一个关于memset 的好问题,我不知道。无论哪种方式,它都会编译。我将向fopen 添加错误检查,这是一个很好的建议,谢谢,但它正在写入文件,所以我认为这不是问题。而且......我又不是很擅长C,但我想我也试图去掉memset这一行,因为我也想,“谁需要它?”但它开始弄乱我的输出,所以我把它放回去了。
  • @yano,回答你关于memset 的问题,我只是打错了。在我的实际代码中,不包括第四个参数。

标签: c sockets http file-io


【解决方案1】:

recv返回读取的字节数。

ssize_t rb;
FILE *fp = fopen("output", "wb"); // Open the file for writing
while ((rb = recv(s, buf, sizeof(buf), 0)) > 0) { //This just iterates over our HTTP response, it works don't worry
    fwrite(buf, 1, rb, fp); // <-- **This is not the problem line anymore**
}
flose(fp); // Close the file

【讨论】:

  • 哇!太感谢了!看,我知道这很简单。我已将其标记为正确,但我无法验证肯定,因为我还没有找到在写入文件之前去除标题的方法。我还有另一个问题要解决,但现在文件仍然不同,虽然只有大约 200 字节而不是 1 千字节左右,所以对于顶部塞满 HTTP 标头的文件来说,这感觉是正确的大小。非常感谢!
  • recv 出错时返回 -1,这是真的。 while 循环应该检查 > 0(不想在错误时写入文件并且没有必要写入 0 字节)。
  • 确认!这正是我所需要的,非常感谢@stderr,如果没有你,我永远不会改变fwrite()
  • @ALittleHelpFromMyFriends "我还没有找到在写入文件之前去除标题的方法" - 请参阅 my answerDiffer between header and content of http server response (sockets)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-29
相关资源
最近更新 更多