下載功能是網路應用的基石。早期單線程下載一旦中斷便須重頭再來;隨著「斷點續傳」與「多線程下載」技術成熟,現代下載器已能大幅提升效率與穩定性。本文基於 C++Builder 5.0 與 WinInet API,詳細闡述支援續傳與多線程的下載模組設計,涵蓋 HTTP 協議基礎、連線建立、檔案資訊查詢、資料讀寫、資源釋放、續傳邏輯、多線程分塊與合併、執行緒同步等核心環節。
下載本質是透過 HTTP GET 向 Web 伺服器請求檔案。WinInet 封裝了 Socket 細節,核心呼叫鏈為:
InternetOpen → 取得會話句柄 hSessionInternetConnect → 取得連線句柄 hConnectHttpOpenRequest → 取得請求句柄 hRequest(指定 GET、HTTP/1.1、Accept: */*)HttpSendRequest 發送請求HttpQueryInfo 取得 Content-Length 等資訊InternetReadFile 迴圈讀取資料塊InternetCloseHandle 依序釋放三層句柄
圖一:WinInet 核心 API 呼叫順序
THttpGetThread繼承 TThread,FreeOnTerminate = true 自動銷毀。關鍵成員:
char Buffer[HTTPGET_BUFFER_MAX+4];
AnsiString FURL, FOutFileName;
HINTERNET FhSession, FhConnect, FhRequest;
bool FSuccess;
int iFileHandle; // 輸出檔案句柄
StartHttpGet()依序呼叫上述 API,try...catch 捕獲失敗並呼叫 EndHttpGet() 釋放資源。
GetWEBFileSize()HttpQueryInfo(HTTP_QUERY_CONTENT_LENGTH) 解析 Content-Length 標頭,觸發 DoOnGetFileSize 事件供上層分塊使用。
OpenOutFile()若檔案已存在則刪除重建,回傳 FileCreate 句柄。
DoHttpGet()while (true) {
Application->ProcessMessages();
bool ReadReturn = InternetReadFile(FhRequest, Buffer, dwRequest, &dwRead);
if (!ReadReturn || dwRead == 0) break;
Buffer[dwRead] = '\0';
FileWrite(iFileHandle, Buffer, dwRead);
dwCount += dwRead;
DoOnProgress(dwCount); // 進度回呼
}
EndHttpGet()逆序 InternetCloseHandle,並將句柄變數歸零。
Execute()包含重試迴圈(預設 5 次),成功觸發 OnComplete,失敗觸發 OnError。
核心兩步:
OpenOutFile 中若檔案存在,取其大小作為已下載位移,FileSeek(handle, 0, 2) 移至檔尾準備續寫。DoHttpGet 開頭呼叫 InternetSetFilePointer(或 HTTP Range 標頭)將伺服器檔案指標移至續傳位置;若伺服器不支援(SetFilePointer 失敗),則刪除本地檔案重頭下載。THttpGetEx元件化設計,動態建立/銷毀執行緒陣列。
int FIndex; // 陣列索引
DWORD dwStart; // 起始位移
DWORD dwTotal; // 需下載位元組數
DWORD FGetBytes; // 實際下載量
DoHttpGet 迴圈中依 dwTotal 修正讀取長度與結束條件。
CreateHttpThreads()FileSizeAvgSize = FileSize / ThreadCount,最後一塊補齊餘數SetFilePointer(CanMulti)StartPostion、GetBytes、獨立暫存檔 OutTmpFiles[i]DownLoadFile()遍歷陣列呼叫 Resume() 啟動所有執行緒。
OnThreadComplete建立命名互斥體 http-get-thread-mutex 確保同一時間僅有一個執行緒進入合併邏輯:
FSuccesss[Index] = true;
bool allDone = true;
for (int i=0; i
Execute 中的重試機制可擴充為指數退避InternetOpen 指定 INTERNET_FLAG_ASYNC 並配合回呼函數,可避免阻塞 UI 執行緒LARGE_INTEGER)突破 2GB 限制Synchronize 或訊息佇列更新 UI本文提供一套可直接落地的 C++Builder 下載模組原始碼架構,涵蓋從單線程基礎到多線程分塊、續傳邏輯、執行緒同步與檔案合併的完整鏈路。開發者可據此擴充支援 HTTPS、Proxy、限速、校驗等進階功能,打造生產級下載元件。