2012-04-21 71 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

相關問題