2009-11-21 87 views
0

我有一臺運行在本地機器上的代理服務器,用於在瀏覽時緩存圖像。我使用代理將瀏覽器設置爲127.0.0.1,接收HTTP請求,獲取數據並將其發送回瀏覽器。它適用於除大型圖像以外的所有應用。當我接收圖像信息,只顯示一半的圖像(例如:谷歌標誌的上半部分)繼承人我的代碼:通過winsocket接收圖像

char buffer[1024] = ""; 
    string ret(""); 
    while(true) 
    { 
     valeurRetour = recv(socketClient_, buffer, sizeof(buffer), 0); 
     if(valeurRetour <= 0) break; 
     string t; 
     t.assign(buffer,valeurRetour); 
     ret += t; 
     longueur += valeurRetour; 
    } 
    closesocket(socketClient_); 
    valeurRetour = send(socketServeur_, ret.c_str(),longueur, 0); 

的socketClient_是非阻塞的。任何想法如何解決這個問題?

回答

2

您在recv的可能返回值中沒有做出足夠的區分。

這裏有兩個級別。

首先是,你將0和-1混合在一起。 0表示遠程節點關閉了它的一半連接,所以你的代碼在這裏做了正確的事情,也關閉了它的套接字。 -1表示除了接收數據之外發生了一些事情它可能是一個永久性錯誤,一個暫時的錯誤,或者只是一個從堆棧發出的通知,除了收到數據之外發生了一些事情。你的代碼將所有這些可能性結合在一起,並且在遠程對等關閉連接時將它們視爲相同。

第二個等級是,並不是所有從recv獲得-1的原因都是「錯誤」,因爲套接字不再有用。我想如果你開始檢查-1,然後打電話WSAGetLastError找出你爲什麼得到-1,你會得到WSAEWOULDBLOCK,這是正常的,因爲你有一個非阻塞套接字。這意味着recv調用不能返回數據,因爲它必須阻止程序的執行線程才能這樣做,並且你告訴Winsock你想要非阻塞調用。

一個天真的修復方法是不打破WSAEWOULDBLOCK的循環,但這只是意味着你一次又一次地調用recv,直到它返回數據爲止。這違背了非阻塞套接字的全部要點,即它們讓您的程序在網絡繁忙時做其他事情。你應該使用像select,WSAAsyncSelectWSAEventSelect這樣的函數在API函數的調用很可能再次成功時被通知。在此之前,你不會這樣稱呼它。您可能想訪問The Winsock Programmer's FAQ。 (免責聲明:我是其維護者。)

0

您是否分析了HTTP級別的事務,即檢查了標題?

你是否會考慮諸如Chunked傳輸的內容?

我沒有明確的答案,部分原因是由於缺乏這裏給出的細節。