我使用winsock2从网上下载文件的字节。到目前为止一切都很好 我有一个问题,我下载我的字节,包括我不需要的http标头,这会导致我的文件字节码出现问题。
示例:
我知道通过查找" \ 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 :(得分: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周期。