我需要以块的形式下载一个html页面。我已经构建了一个GET reuest,可以下载一定范围的数据。但我不能以重复的方式做到这一点。 基本上我必须首先收到0-99字节然后100-199等等...... 另外,我很高兴知道如何使用c或c ++代码预先知道接收文件的确切大小。 以下是我的代码。 我已经成功地将连接器豁免到插座等。
int c=0,s=0;
while(1)
{
get = build_get_query(host, page,s);
c+=1;
fprintf(stderr, "Query is:\n<<START>>\n%s<<END>>\n", get);
//Send the query to the server
int sent = 0;
cout<<"sending "<<c<<endl;
while(sent < strlen(get))
{
tmpres = send(sock, get+sent, strlen(get)-sent, 0);
if(tmpres == -1)
{
perror("Can't send query");
exit(1);
}
sent += tmpres;
}
//now it is time to receive the page
memset(buf, 0, sizeof(buf));
int htmlstart = 0;
char * htmlcontent;
cout<< "reciving "<<c<<endl;
while((tmpres = recv(sock, buf, BUFSIZ, 0)) > 0)
{
if(htmlstart == 0)
{
/* Under certain conditions this will not work.
* If the \r\n\r\n part is splitted into two messages
* it will fail to detect the beginning of HTML content
*/
htmlcontent = strstr(buf, "\r\n\r\n");
if(htmlcontent != NULL)
{
htmlstart = 1;
htmlcontent += 4;
}
}
else
{
htmlcontent = buf;
}
if(htmlstart)
{
fprintf(stdout, htmlcontent);
}
memset(buf, 0, tmpres);
}
if(tmpres < 0)
{
perror("Error receiving data");
}
s+=100;
if(c==5)
break;
}
char *build_get_query(char *host, char *page,int i)
{
char *query;
char *getpage = page;
int j=i+99;
char tpl[100] = "GET /%s HTTP/1.1\r\nHost: %s\r\nRange: bytes=%d-%d\r\nUser- Agent: %s\r\n\r\n";
if(getpage[0] == '/')
{
getpage = getpage + 1;
fprintf(stderr,"Removing leading \"/\", converting %s to %s\n", page, getpage);
}
query = (char *)malloc(strlen(host)+strlen(getpage)+8+strlen(USERAGENT)+strlen(tpl)-5);
sprintf(query, tpl, getpage, host, i , j, USERAGENT);
return query;
}
答案 0 :(得分:2)
另外,我很高兴知道如何使用c或c ++代码预先知道接收文件的确切大小。
如果服务器支持对特定资源的范围请求(无法保证),那么答案将如下所示:
HTTP/1.1 206 partial content
Content-Range: bytes 100-199/12345
这意味着响应将包含字节100..199,并且内容的总大小为12345字节。
这里有很多问题涉及解析HTTP头,因此我不会详细介绍如何专门使用C / C ++从头中提取这些数据。
另请注意,您正在执行HTTP / 1.1请求,因此必须处理可能的分块响应并隐式保持活动状态。我真的建议使用现有的HTTP库,而不是手动完成并做错。如果您真的想自己实施,请学习the specification of HTTP。