簡體   English   中英

如果將大文件加載到C Web服務器的內存緩沖區中會發生什么

[英]What will happen if big file will be loaded in memory buffer in C webserver

我正在用C語言制作一個簡單的Web服務器,以便出於教育目的提供靜態文件。 我做了一個將文件發送到客戶端的函數,它為整個文件分配了內存塊。 如果服務器硬件具有4 GB的內存,並且客戶端請求大的文件(例如,具有5 GB的數據庫文件),該怎么辦? 它不會使我的應用程序崩潰嗎?

我的serve_file函數的主體(請注意,省略了錯誤處理):

long fsize;
FILE *fp = fopen(filename, "rb");
fseek(fp, 0, SEEK_END);
fsize = ftell(fp);
rewind(fp);

char *buf = (char*) malloc(fsize);

fread(buf, fsize, 1, fp);

Server_TCP_Send(socket, buf, fsize);
fclose(fp);
free(buf);

最好的方法是使用循環以可管理的塊讀取和提供數據。 這樣,文件的大小無關緊要。 您的方法可能會或可能不會導致系統崩潰。 如果它沒有崩潰,則可能會開始使用虛擬內存將數據分頁到磁盤。 這將導致大量的崩潰並降低系統速度,如果嘗試運行其他程序,則尤為糟糕。

如果服務器硬件具有4 GB的內存,並且客戶端請求大的文件(例如,具有5 GB的數據庫文件),該怎么辦? 它不會使我的應用程序崩潰嗎?

也許。 也許不吧。 C標准中沒有任何內容直接說明這個問題。 即使在實踐中,C實現支持的分配對象的大小也不一定要限制為物理內存的大小。 現代機器具有虛擬內存系統,可以想象可以支持您所描述的分配。 如果確實分配成功,則沒有特殊理由認為服務器將崩潰。

這里的主要風險是您不檢查分配是否成功。 如果發生失敗,則malloc()調用將返回空指針。 將空指針作為fread()的第一個參數傳遞將產生未定義的行為。 在這種情況下,這很可能表現為崩潰,但並非必須這樣做。 如果檢查malloc()調用的返回值,則可以正常地失敗而不是崩潰。

我注意到您也不會檢查fread()的返回值。 如果失敗,則最終可能會將垃圾發送到客戶端。 通常,如果確實關心是否發生任何錯誤,則應檢查函數調用的返回值以獲取錯誤指示符。

話雖如此,確實有更好的方法來完成您要嘗試做的事情。 除了存在很大的失敗風險外,在發送整個文件之前將其讀取到內存中可能會導致在開始實際傳輸到客戶端之前出現明顯的延遲。 對於自動或自然超時來說,可能已經足夠了。 從這種意義上講,以較小的塊讀取很有可能會更快。 也有其他選擇,例如將文件映射到內存而不是實際讀取文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM