【问题标题】:How to Strip the header from data received using recv in c++?c++ - 如何从使用c ++中的recv接收的数据中去除标头?
【发布时间】:2020-12-18 23:37:41
【问题描述】:

我在下面制作了这段代码来下载大文件并将其保存到文件中。 (我删除了不重要的部分)

int nDataLength;
int i = 0;
static char buffer[4096];
while ((nDataLength = recv(Socket, buffer, sizeof(buffer), NULL)) > 0)
{
    //MessageBoxA(0, std::to_string(nDataLength).c_str(), "TEST", 0);
    fwrite(buffer, nDataLength, 1, pFile);
}

现在它保存文件,但它也保存 HTTP 标头。现在我真的不知道如何从接收到的数据中去除标头。
如果它足够小,我可以从缓冲区读取 Content-Length,然后再次打开文件并删除标题,但这不是选项,因为缓冲区将被新数据覆盖。

我也不能使用 libcurl 等其他库。

编辑:

char* content = strstr(buffer, "\r\n\r\n");
    if (content != NULL) {
        content += 4;
        fwrite(content, nDataLength, 1, pFile);
    }
    else
    {
        fwrite(buffer, nDataLength, 1, pFile);
    }

【问题讨论】:

  • HTTP 规范将详细地告诉您 HTTP 消息的格式以及标头结束的确切位置以及内容的开始位置。您熟悉 HTTP 技术规范吗?这是一个免费提供的文档。
  • 只写数据,不写表头。为此,您必须解析标头...开始简单,将整个数据写入临时文件、标头和所有内容。然后编写一个单独的函数(甚至是一个程序),它获取临时文件,解析标题,然后将正确的数据写入最终文件。一旦你可以做到这一点,然后尝试将其组合起来,这样你就不需要临时文件了。
  • @SamVarshavchik 我知道数据在 \r\n\r\n 之后开始,但我不知道如何剥离它。
  • @hyde 我做得对,我知道数据在 /r/n 之后,但如果没有 tempfile,我无法复制它。
  • 直到/r/n/r/n才知道怎么丢弃。我添加了我想出的示例代码(看看我的问题),但它却将标头数据添加到缓冲区的末尾。另外我对 c++ 还很陌生,所以我可能会遗漏一些东西。

标签: c++ winsock


【解决方案1】:

好的,我想出了在保存之前去除标题的功能。

 int nDataLength;
int i = 0;
static char buffer[4096];
while ((nDataLength = recv(Socket, buffer, sizeof(buffer), NULL)) > 0)
{
    char* content = strstr(buffer, "\r\n\r\n");
    if (content != NULL) {
        std::string s2(buffer); 
        size_t p = s2.find("\r\n\r\n");
        fwrite(buffer+p+4, nDataLength-p-4, 1, pFile);
    }
    else
    {
        fwrite(buffer, nDataLength, 1, pFile);
    }
    
}

【讨论】:

  • recv() 读取任意数量的字节。无法保证buffer 一次会包含完整的"\r\n\r\n"。此外,recv() 不会以 null 终止它返回的数据,但 strstr() 需要一个以 null 结尾的字符串(您正在使用的 std::string 构造函数也是如此)。所以,这个函数,正如所写的,不会 100% 正确工作。此外,将strstr()string::find() 一起使用是多余的。
  • 你能提供这个函数的源码吗?我会将其标记为答案。
  • 那是您的选择,但是由于几个原因,您的解决方案完全是错误的,并且最终会失败,这就是我否决它的原因。过去,我发布了许多答案,解释/展示了读取 HTTP 响应的 正确 方式。例如:stackoverflow.com/a/30472253/65863stackoverflow.com/a/7234357/65863stackoverflow.com/a/16247097/65863stackoverflow.com/a/14421507/65863
猜你喜欢
  • 2016-07-23
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
  • 2017-05-27
  • 1970-01-01
  • 2023-03-13
相关资源
最近更新 更多