C ++ Winsock下载文件切断HTTP标头

时间:2016-07-23 14:28:12

标签: c++ windows file download winsock

我使用winsock2从网上下载文件的字节。到目前为止一切都很好 我有一个问题,我下载我的字节,包括我不需要的http标头,这会导致我的文件字节码出现问题。

示例:Example

我知道通过查找" \ r \ n \ r \ n"我可以找到标题结束的位置。 但不知怎的,我无法找到或至少削减它...... :(

int iResponseBytes = 0;
ofstream ofDownloadedFile;
ofDownloadedFile.open(pathonclient, ios::binary);
do {
    iResponseBytes = recv(this->Socket, responseBuffer, pageBufferSize, 0);
    if (iResponseBytes > 0)     // if bytes received
    {
        ofDownloadedFile.write(responseBuffer, pageBufferSize);
    }
    else if (iResponseBytes == 0) //Done
    {
        break;
    }
    else //fail
    {
        cout << "Error while downloading" << endl;
        break;
    }
} while (iResponseBytes > 0);

我尝试使用strncmp等搜索数组/指针。 希望有人可以帮助我。

最好的问候

1 个答案:

答案 0 :(得分:0)

您无法保证在\r\n\r\n次通话中完全接收recv()序列。

例如,第一个recv()调用最终可能会读取所有内容,直到序列的前两个字符\r\n,然后您的代码再次在循环中运行,第二次recv() 1}}被调用它接收剩余的\r\n,用于接收的初始两个字节(后跟实际内容的第一部分)。这可能发生的可能性很小,但不能忽视,必须正确处理。

如果您的目标是在\r\n\r\n之前修改所有内容,那么您当前的方法将无法正常运行。

相反,你应该做的是花些时间研究文件流缓冲实际上是如何工作的。暂时说明,std::istream / std::ostream一次如何读/写大块数据,但它们提供了面向字符的界面。例如,std::istream一次读取一个缓冲区的文件数据,将其放入内部缓冲区,然后您的代码可以一次检索一个字符(如果愿意的话)。这是如何运作的?想一想。

要正确执行此操作,您需要自己实现相同的算法:recv()一次从套接字缓冲区,然后提供面向字节的接口,一次一个字节地返回接收的内容。

然后,主代码变成一个简单的循环,一次读取一个字节的流式套接字内容,此时丢弃所有内容直到代码看到\r\n\r\n变得微不足道(尽管还有一些非这样做有明显的好处,但这可能是一个新问题。)

当然,一旦\r\n\r\n被处理,通过将内部仍然缓冲的内容刷新到输出文件,然后从套接字继续读取,当然可以优化前进的事情。一次整个缓冲区,并将其复制到输出文件,而不会烧掉处理面向字节的接口的CPU周期。