WinInet (Windows Internet API) 是 Windows 提供的高層網絡 API,支持 HTTP、FTP、Gopher 協議,比 WinSock 更簡單易用,適合快速實現 HTTP 客戶端功能。
#include <stdio.h>
#include <windows.h>
#include <wininet.h>
#define MAXSIZE 1024
#pragma comment(lib, "Wininet.lib")
void urlopen(TCHAR* url);
int main(int argc, TCHAR* argv[]) {
TCHAR url[] = TEXT("https://dt.163.com/images/news/0605/news02053101_5.jpg");
urlopen(url);
getchar();
return 0;
}
void urlopen(TCHAR* url) {
// 1. 初始化會話
HINTERNET hSession = InternetOpen(
TEXT("UrlTest"), // 用戶代理
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY, // 使用系統代理設置
NULL, NULL, 0
);
if (!hSession) return;
// 2. 打開 URL 連接
HINTERNET hHttp = InternetOpenUrl(
hSession, url, NULL, 0,
INTERNET_FLAG_DONT_CACHE, // 不緩存
0
);
if (!hHttp) {
InternetCloseHandle(hSession);
return;
}
// 3. 創建本地文件
HANDLE hFile = CreateFile(
TEXT("ysl.jpg"), GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
);
if (hFile == INVALID_HANDLE_VALUE) {
InternetCloseHandle(hHttp);
InternetCloseHandle(hSession);
return;
}
// 4. 循環讀取並寫入
BYTE buffer[MAXSIZE];
ULONG bytesRead = 1;
DWORD bytesWritten;
while (bytesRead > 0) {
InternetReadFile(hHttp, buffer, MAXSIZE - 1, &bytesRead);
if (bytesRead > 0) {
WriteFile(hFile, buffer, bytesRead, &bytesWritten, NULL);
}
}
// 5. 清理資源
CloseHandle(hFile);
InternetCloseHandle(hHttp);
InternetCloseHandle(hSession);
}
InternetOpen() → 會話句柄
↓
InternetOpenUrl() → 連接句柄 (HTTP GET)
↓
InternetReadFile() → 讀取數據塊 (循環直到返回 0)
↓
WriteFile() → 寫入本地文件
↓
InternetCloseHandle() × 3 → 釋放所有句柄
| API | 關鍵參數 | 說明 |
|---|---|---|
| InternetOpen | lpszAgent | User-Agent 標識,服務器可據此拒絕/統計 |
| InternetOpen | dwAccessType | INTERNET_OPEN_TYPE_PRECONFIG: 使用 IE 設置 |
| InternetOpenUrl | lpszHeaders | 額外 HTTP 頭,NULL 為無 |
| InternetOpenUrl | dwFlags | INTERNET_FLAG_DONT_CACHE: 繞過緩存直接下載 |
| InternetReadFile | lpdwNumberOfBytesRead | 輸出參數,實際讀取字節數,0 表示結束 |
| CreateFile | dwCreationDisposition | CREATE_ALWAYS: 新建/覆蓋 |
DWORD err = GetLastError();
if (err != ERROR_SUCCESS) {
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf, 0, NULL
);
printf("Error %lu: %s\n", err, (char*)lpMsgBuf);
LocalFree(lpMsgBuf);
}
HttpOpenRequest + HttpSendRequest 替代 InternetOpenUrlRange 頭 + InternetSetFilePointerINTERNET_FLAG_ASYNC + 回調函數InternetSetOption 設置 INTERNET_OPTION_PROXY_USERNAME/PASSWORD#include <wininet.h>#pragma comment(lib, "Wininet.lib") 或鏈接器添加 Wininet.libTCHAR/TEXT() 宏保證雙字符集兼容