2016-07-23 43 views
1

我正在使用winsock2从网上下载文件的字节。迄今为止很好。 我有问题,我下载我的字节,包括我不需要的HTTP标头,这会导致我的文件字节码出现问题。C++ Winsock下载文件切断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等搜索阵列/指针 希望有人能帮助我。

最好的问候

回答

0

你有没有保证,任何,该\r\n\r\n序列将一个recv()调用内完全接收。

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

如果您的目标是将所有内容修剪至\r\n\r\n,那么您目前的方法不会奏效。

相反,你应该做的是花一些时间研究文件流缓冲如何实际工作。一时间,Pontificate认为,如何一次读取/写入大块数据,但他们提供了一个面向字符的接口。例如,一次读取一个缓冲区的全部文件数据,并将其放入一个内部缓冲区,然后您的代码可以一次检索一个字符(如果它希望的话)。这是如何运作的?想想看。

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

然后,主代码变成一个简单的循环,一次读取一个字节的流式套接字内容,在这一点上丢弃所有东西,直到代码看到\r\n\r\n变得微不足道(尽管仍然有一些不明显的陷阱这样做是正确的,但这可能是一个新问题)。

当然,一旦\r\n\r\n得到处理,通过将内部仍然缓冲的任何内容清空到输出文件,然后继续从套接字读取整个buffer-at-a,当然可以优化前进的事情并将其复制到输出文件,而不会烧毁处理面向字节接口的CPU周期。