2012-04-21 53 views
1

现在我已经有了一个url列表,我想要返回所有的网页。这里是我做了什么:我可以保持与http服务器连接吗?

for each url: 
    getaddrinfo(hostname, port, &hints, &res);   // DNS 
    // create socket 
    sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 
    connect(sockfd, res->ai_addr, res->ai_addrlen); 
    creatGET(); 
    /* for example: 
     GET/HTTP/1.1\r\n 
     Host: stackoverflow.cn\r\n 
     ... 
     */ 
    writeHead(); // send GET head to host 
    recv();  // get the webpage content 
end 

我注意到,许多URL的是相同的主机下,例如:

http://job.01hr.com/j/f-6164230.html 
http://job.01hr.com/j/f-6184336.html 
http://www.012yy.com/gangtaiju/32692/ 
http://www.012yy.com/gangtaiju/35162/ 

所以我不知道,我能connect只有一次,每个主机和那么每个网址只需creatGET(),writeHead()recv()?这可能会节省很多时间。所以我改变了我的计划是这样的:

split url into groups by their host; 
for each group: 
    get hostname in the group; 
    getaddrinfo(hostname, port, &hints, &res);   
    sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 
    connect(sockfd, res->ai_addr, res->ai_addrlen); 
    for each url in the group:   
     creatGET(); 
     writeHead(); 
     recv(); 
    end 
end 

不幸的是,我发现我的程序只能获得各组第一网页回来,其余全部返回空文件。 我错过了什么吗?也许sockfd需要某种reset每个recv()?

谢谢你的慷慨帮助。

+1

你使用的标题'连接明确地表示:保持Alive'?不是所有的网络服务器都可以遵守它,所以你应该准备在电流关闭时打开一个新的连接。 – 2012-04-21 08:09:54

回答

2

HTTP 1.1连接是持久的,这意味着在例如一个POST/GET - 200 OK序列,下一个请求 - 响应序列可以重新使用已经建立的TCP连接。
但这不是强制性的。连接可能随时关闭,所以您应该为此编写代码。

此外,在我看来,你正试图实现自己的HTTP客户端。
我不知道你为什么要这样做,但无论如何,如果你必须读一点关于HTTP RFC来理解各种头文件,以确保底层TCP连接尽可能打开。

当然,如果你的服务器是一个古老的HTTP1.0你不应该期望的任何连接重用,除非通过保活头

+0

我将“Connnection”设置为“Keep-Alive”,但似乎没有效果。这只是一个练习,我想做一些改进。 – Flybywind 2012-04-21 08:48:55

+0

使用wireshark查看通信流程。是否可以以某种方式关闭连接? – Cratylus 2012-04-21 09:29:08

相关问题