2016-07-23 83 views
1

我正在使用winsock2從網上下載文件的字節。迄今爲止很好。 我有問題,我下載我的字節,包括我不需要的HTTP標頭,這會導致我的文件字節碼出現問題。C++ Winsock下載文件切斷HTTP頭

實施例:Example

我知道可以找到其中報頭通過找到爲 「\ r \ n \ r \ n」 個結束的位置。 但不知何故,我無法找到或至少削減它... :(

int iResponseBytes = 0; 
ofstream ofDownloadedFile; 
ofDownloadedFile.open(pathonclient, ios::binary); 
do { 
    iResponseBytes = recv(this->Socket, responseBuffer, pageBufferSize, 0); 
    if (iResponseBytes > 0)  // if bytes received 
    { 
     ofDownloadedFile.write(responseBuffer, pageBufferSize); 
    } 
    else if (iResponseBytes == 0) //Done 
    { 
     break; 
    } 
    else //fail 
    { 
     cout << "Error while downloading" << endl; 
     break; 
    } 
} while (iResponseBytes > 0); 

我嘗試使用STRNCMP等搜索陣列/指針 希望有人能幫助我。

最好的問候

回答

0

你有沒有保證,任何,該\r\n\r\n序列將一個recv()調用內完全接收。

例如,第一recv()調用可能最終會讀取所有內容,直到序列的前兩個字符爲\r\n,然後您的代碼再次在該循環中運行,並且第二次調用recv()可以調用它接收剩餘的\r\n,以獲得最初收到的兩個字節(隨後是第一部分的實際內容)。發生這種情況的可能性很小,但不能忽視,必須正確處理。

如果您的目標是將所有內容修剪至\r\n\r\n,那麼您目前的方法不會奏效。

相反,你應該做的是花一些時間研究文件流緩衝如何實際工作。一時間,Pontificate認爲,如何一次讀取/寫入大塊數據,但他們提供了一個面向字符的接口。例如,一次讀取一個緩衝區的全部文件數據,並將其放入一個內部緩衝區,然後您的代碼可以一次檢索一個字符(如果它希望的話)。這是如何運作的?想想看。

要正確執行此操作,您需要自己實現相同的算法:recv()從套接字緩衝區中一次,然後提供一個面向字節的接口,一次返回一個字節的接收內容。

然後,主代碼變成一個簡單的循環,一次讀取一個字節的流式套接字內容,在這一點上丟棄所有東西,直到代碼看到\r\n\r\n變得微不足道(儘管仍然有一些不明顯的陷阱這樣做是正確的,但這可能是一個新問題)。

當然,一旦\r\n\r\n得到處理,通過將內部仍然緩衝的任何內容清空到輸出文件,然後繼續從套接字讀取整個buffer-at-a,當然可以優化前進的事情並將其複製到輸出文件,而不會燒燬處理面向字節接口的CPU週期。