C++ Winsock 下载文件切断 HTTP header

标签 c++ windows file download winsock

我正在使用 winsock2 从 Web 下载文件的字节。到目前为止这么好。 我有一个问题,我下载了我的字节,包括我不需要的 http header ,这会导致我的文件字节码出现问题。

示例: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 等搜索数组/指针。 希望有人能帮助我。

最好的问候

最佳答案

您无法保证 \r\n\r\n 序列将在单个 recv() 调用中被完整接收。

例如,第一个 recv() 调用可能会读取序列的前两个字符 \r\n 之前的所有内容,然后您的代码将运行再次绕过循环,第二次 recv() 被调用时,它接收剩余的 \r\n 用于收到的初始两个字节(后面是第一部分实际内容)。发生这种情况的可能性很小,但也不容忽视,必须正确处理。

如果您的目标是裁剪 \r\n\r\n 之前的所有内容,则您当前的方法不会很有效。

相反,您应该花一些时间研究文件流缓冲的实际工作原理。教皇,暂时,std::istream/std::ostream 如何一次读取/写入大块数据,但它们提供面向字符的接口(interface)。 std::istream,例如,一次读取缓冲区的全部文件数据,将其放入内部缓冲区,然后您的代码可以一次检索一个字符(如果需要) .这是如何运作的?想一想。

要正确地做到这一点,您需要自己实现相同的算法:recv() 一次从套接字中获取一个缓冲区,然后提供一个面向字节的接口(interface),将接收到的内容返回一个一次一个字节。

然后,主代码变成了一个简单的循环,一次读取一个字节的流套接字内容,此时丢弃所有内容,直到代码看到 \r\n\r\n 变为微不足道(尽管在正确执行此操作时仍然存在一些不明显的陷阱,但这可能是一个新问题)。

当然,一旦 \r\n\r\n 得到处理,肯定有可能通过将仍在内部缓冲的内容刷新到输出文件来优化 future 的事情,并且然后恢复一次从套接字读取整个缓冲区,并将其复制到输出文件,而不会消耗处理面向字节的接口(interface)的 CPU 周期。

关于C++ Winsock 下载文件切断 HTTP header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38542861/

相关文章:

c++ - 进行 SendInput 时调用全局低级键盘 Hook 。如何预防?

c++ - 使用 g++ 编译器打印 C++ 对象的布局

windows - Windows 2012 如何选择 Internet 与 DataCenter 的网络过滤器设置,如 netstat -y 中所示

python - 在 python 中复制(重复)文件

c - 未在命令行上指定输入文件时出现段错误

c++ - 二维数组未显示正确的输出

c++ - 字符串比较的动态编程

c++ - 如何结合RegisterDragDrop,RoInitialize在一个线程中一起工作?

windows - 如何在Windows上使用clang从命令行传递链接描述文件?

java - java中使用文件作为大Map的存储介质