首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Windows HTTP 協議編程實戰:WinInet API 實現圖片下載完整示例

     編輯:關於C語言

WinInet 簡介

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);
}

關鍵 API 流程圖

InternetOpen() → 會話句柄
    ↓
InternetOpenUrl() → 連接句柄 (HTTP GET)
    ↓
InternetReadFile() → 讀取數據塊 (循環直到返回 0)
    ↓
WriteFile() → 寫入本地文件
    ↓
InternetCloseHandle() × 3 → 釋放所有句柄

重要參數詳解

API關鍵參數說明
InternetOpenlpszAgentUser-Agent 標識,服務器可據此拒絕/統計
InternetOpendwAccessTypeINTERNET_OPEN_TYPE_PRECONFIG: 使用 IE 設置
InternetOpenUrllpszHeaders額外 HTTP 頭,NULL 為無
InternetOpenUrldwFlagsINTERNET_FLAG_DONT_CACHE: 繞過緩存直接下載
InternetReadFilelpdwNumberOfBytesRead輸出參數,實際讀取字節數,0 表示結束
CreateFiledwCreationDispositionCREATE_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);
}

進階擴展方向

  1. POST 請求:用 HttpOpenRequest + HttpSendRequest 替代 InternetOpenUrl
  2. HTTPS 支持:自動支持,需確保系統有對應根證書
  3. 斷點續傳:使用 Range 頭 + InternetSetFilePointer
  4. 異步下載:INTERNET_FLAG_ASYNC + 回調函數
  5. 代理認證:InternetSetOption 設置 INTERNET_OPTION_PROXY_USERNAME/PASSWORD

編譯鏈接提示

  • 頭文件:#include <wininet.h>
  • 庫文件:#pragma comment(lib, "Wininet.lib") 或鏈接器添加 Wininet.lib
  • Unicode 項目使用 TCHAR/TEXT() 宏保證雙字符集兼容
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved