2013-08-05 22 views
0

我正在編寫一個web代理,它可以很好地處理可以轉換爲ASCII文本的網頁。但是,當我嘗試使用二進制數據(Youtube.com是我一直在使用的那個)查看頁面時,有一處存在內存泄漏,並且在字符串的末尾,相同的幾個字符會一遍又一遍地重複發送給客戶(並且將顯示在其他地方,他們顯然不應該)。C socket只能用二進制數據製作內存泄露

下面是我的代碼的相關部分。 SendHTTPResponse是一個函數,它使用代理將網頁的響應發送給客戶端,並且正常工作。

有沒有人有任何見解?

int numBytes; 
char temp[3000]; 
memset(temp, '\0', 3000); 
numBytes = Read(internetSocket, temp, 2999); 
while (errno = 0, numBytes > 0 || errno == EINTR) 
{ 
    SendHTTPResponse(socket, temp, numBytes); 
    memset(temp, '\0', 3000); 
    numBytes = Read(internetSocket, temp, 2999);  
} 
+0

沒有足夠的信息或代碼來回答這個問題。您需要進行一些調試並縮小範圍。 –

+0

難道你不需要接受numBytes == 0作爲有效的返回值,這意味着什麼都沒有在緩衝區中,但流仍然打開,你應該繼續嘗試閱讀? –

+4

errno = 0,numBytes> 0 ????那是什麼?你爲什麼要用這樣的逗號運算符?爲什麼你將errno設置爲0? –

回答

1

要回答你的問題,這段代碼沒有內存泄漏。

也沒有理由認爲內存泄漏與此問題有任何關係。

但是你的代碼是錯誤的。它不應該設置errno,它不應該測試它,除非該方法返回-1。它應該閱讀:

while ((numBytes = Read(socket, temp, sizeof temp)) > 0 || numBytes == -1 && errno == EINTR) 
{ 
    SendHTTPResponse(socket, temp, numBytes); 
} 

你不需要memset()電話,用戶不必留下任何餘地尾隨空,提供SendHTTPResponse()需要你通過它的長度適當的通知。它當然不應該尋找拖曳的空值本身。

和3000是一個非常奇怪的緩衝區大小。我會自己使用8192。

+0

如果'numBytes'爲-1,由於沒有要發送的數據,所以'SendHTTPResponse()'不應該被調用,但是當'errno'爲'EINTR'時,應該再次調用Read()以繼續讀取。我將使用'do/while'循環,然後在'Read()'實際失敗時使用'break'。 –

0

這只是一個有關您的問題的教育猜測。正如其他人所說,你還沒有發佈足夠的信息來找到你的錯誤。

二進制數據和文本數據最大的區別是(編輯,謝謝EJP)可以包含空('\ 0')字節。如果你正在使用字符串函數(例如strlen()),他們將把它們解釋爲字符串結尾,所以你會錯過數據。

+1

*前*可以包含空字節。 – EJP