现在我有一个网址列表,我希望得到所有网页。这就是我所做的:
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
我注意到许多网址都在同一主机下,例如:
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()?
感谢您的慷慨帮助。
答案 0 :(得分:2)
HTTP 1.1连接是持久的意味着在例如POST / GET - 200 OK序列下一个请求 - 响应序列可以重用已经建立的TCP连接 但这不是强制性的。连接可以随时关闭,因此您也应该为此编码。
在我看来,您正在尝试实现自己的HTTP客户端 我不确定你为什么要这样做,但无论如何你必须阅读一些关于HTTP RFC的内容,以了解各种标头,以确保底层TCP连接尽可能长时间打开。
当然,如果您的服务器是旧的HTTP1.0,除非通过keep-alive标头明确指出,否则您不应期望重用连接