2011-05-29 46 views
2

我正在用C++編寫一個小型網絡程序。除其他外,它必須下載twitter個人資料照片。我有一個URL列表(stl :: vector)。我認爲我的下一步是創建for-loop並通過套接字發送GET消息並將圖片保存到不同的png文件中。問題是,當我發送第一條消息,接收答案段並保存png數據時,所有事情似乎都很好。但是在下一次迭代中,通過相同套接字發送的相同消息通過recv()函數產生0個接收字節。我通過向循環體添加套接字創建代碼解決了這個問題,但是我對套接字概念有點困惑。它看起來像我發送消息時,套接字應該關閉並再次重新創建,以發送下一條消息到同一臺服務器(爲了獲得下一個圖像)。這是套接字網絡編程的正確方式還是可以通過同一個套接字接收多個HTTP響應消息?爲什麼recv()在所有for循環迭代中返回'0'字節,除了第一個?

在此先感謝。

UPD:這裏是我創建套接字的循環代碼。

// Get links from xml. 
    ... 
    // Load images in cycle. 
    int i=0; 
    for (i=0; i<imageLinks.size(); i++) 
    { 
     // New socket is returned from serverConnect. Why do we need to create new at each iteration? 
     string srvAddr = "207.123.60.126"; 
     int socketImg = serverConnect(srvAddr); 
     // Create a message. 
     ... 
     string message = "GET " + relativePart; 
       message += " HTTP/1.1\r\n"; 
     message += "Host: " + hostPart + "\r\n"; 
     message += "\r\n"; 
     // Send a message. 
     BufferArray tempImgBuffer = sendMessage(sockImg, message, false); 
     fstream pFile; 
     string name; 
     // Form the name. 
     ... 
     pFile.open(name.c_str(), ios::app | ios::out | ios::in | ios::binary); 
     // Write the file contents. 
     ... 
     pFile.close(); 
     // Close the socket. 
     close(sockImg); 
    } 
+5

你應該發佈相關的代碼。一大段文字不太有用。 – Gabe 2011-05-29 11:37:35

+0

我明白這一點。但代碼太大,我不知道在這裏發佈什麼部分。我只是想問一下套接字的實現。它是關閉連接的默認行爲嗎?因爲我覺得有點奇怪。我可以通過同一個套接字接收所有消息(所有圖像)。爲什麼我需要爲每個圖像重新創建一次? – 2011-05-29 11:43:57

+0

學習如何成爲程序員的一個重要部分就是弄清楚如何提取與問題相關的代碼的基本部分。這也是你如何找出答案的地方,並且結合瞭解互動的另一方面是你如何避免首先提出問題。在這種情況下,您應該閱讀HTTP規範並考慮您的代碼如何實現它。哦,@ cnicutar的答案可能是你的問題的答案。 – janm 2011-05-29 11:55:41

回答

6

對方正在關閉連接。這就是HTTP/1.0的工作原理。您可以:

  • 讓每個HTTP不同的連接GET
  • 使用HTTP/1.0與非官方Connection: Keep-Alive
  • 使用HTTP/1.1。在HTTP 1.1中,除非另有聲明,否則所有連接均被視爲持久連接。

強制性XKCD鏈路Server Attention Span

Wiki HTTP

HTTP (HTTP/1.0)的原始版本在HTTP/1.1進行了修訂。 HTTP/1.0用來 每 請求 - 響應事務同一服務器的單獨連接,而 HTTP/1.1可以 多次

3

HTTP以其原始形式重複使用的連接(HTTP 1.0)的確「每個連接一個請求」協議。一旦你得到迴應,另一方可能關閉了連接。爲了支持每個連接的多個請求,某些實現中添加了非官方機制,但它們並未標準化。

HTTP 1.1 turns this around。所有連接默認爲「持久」。

要使用此功能,您需要在請求行的末尾添加「HTTP/1.1」。而不是GET http://someurl/,做GET http://someurl/ HTTP/1.1。當你這樣做時,你還需要確保你提供了「Host:」標題。

但是,請注意,即使一些其他兼容HTTP服務器可能不支持持久連接。還要注意的是,連接實際上可能在很少的延遲,一定數量的請求或者隨機的情況下被丟棄。您必須爲此準備好,並準備好重新連接並在您離開的地方繼續發出您的請求。請參閱HTTP 1.1 RFC

相關問題