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

VC++ Winsock 實現簡易 HTTP 客戶端:Socket 連線、GET 請求、回應接收完整範例

     編輯:VC 教學

Winsock 初始化與清理

WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) return FALSE;
// ... 使用 socket ...
WSACleanup();

核心流程:TCP 連線 → 發送 HTTP GET → 接收回應

BOOL HttpClient(LPCTSTR serverIp, int port, LPCTSTR path, LPCTSTR saveFile) {
    SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET) return FALSE;

    sockaddr_in addr = {0};
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(serverIp);

    if (connect(s, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {
        closesocket(s); return FALSE;
    }

    // 建構 HTTP GET 請求
    CStringA request;
    request.Format("GET %s HTTP/1.0\r\nHost: %s\r\nConnection: close\r\n\r\n", path, serverIp);
    
    if (send(s, request, request.GetLength(), 0) == SOCKET_ERROR) {
        closesocket(s); return FALSE;
    }

    // 接收回應並寫檔
    FILE* fp = fopen(saveFile, "wb");
    if (!fp) { closesocket(s); return FALSE; }

    char buf[4096];
    int nRecv;
    while ((nRecv = recv(s, buf, sizeof(buf), 0)) > 0) {
        fwrite(buf, 1, nRecv, fp);
    }
    fclose(fp);
    closesocket(s);
    return TRUE;
}

MFC 對話式專案整合測試

  1. 建立 Dialog-based 專案 HttpTest
  2. 按鈕 IDC_BTN_GET 處理:
void CHttpTestDlg::OnBtnGet() {
    CString strIp = _T("168.160.224.185"); // 電腦世界日報
    CString strPath = _T("/99/tips/");
    CString strFile = _T("index.htm");
    
    if (HttpClient(strIp, 80, strPath, strFile)) {
        AfxMessageBox(_T("下載完成,已儲存為 index.htm"));
        ShellExecute(m_hWnd, _T("open"), strFile, NULL, NULL, SW_SHOW); // 瀏覽器開啟
    } else {
        AfxMessageBox(_T("下載失敗,請檢查網路/伺服器"));
    }
}

HTTP 協議關鍵點補充

項目說明
HTTP/1.0 vs 1.11.0 預設 Connection: close,適合簡易客戶端;1.1 需處理 Chunked 編碼、Keep-Alive
Host 標頭HTTP/1.1 強制要求,虛擬主機必要
回應解析狀態行 → 標頭 (雙 CRLF 分隔) → 實體內容;需處理 Content-Length、Transfer-Encoding: chunked
重導向 (301/302)需解析 Location 標頭,重新發起請求
HTTPS需 SSL/TLS 層 (OpenSSL/Schannel),非純 Socket 可完成

進階:非同步/多執行緒下載

  • 使用 WSAAsyncSelect 或 WSAEventSelect 進行事件驅動
  • 或建立工作執行緒池,每執行緒處理一個連線
  • 大檔案支援斷點續傳:Range: bytes=start-end 標頭

擴充至其他協議

同樣 Socket 架構,僅更換命令字串:

協議Port命令範例
SMTP25HELO / MAIL FROM / RCPT TO / DATA
POP3110USER / PASS / LIST / RETR / QUIT
FTP21USER / PASS / PASV / RETR / STOR
Telnet23協商選項 / 字元流互動
TIME37無命令,連線即回傳 32-bit 秒數 (NTP 前身)

避坑指南

  • send/recv 可能部分發送/接收,生產代碼必須迴圈處理直到完成
  • recv 返回 0 表示對端正常關閉 (EOF);SOCKET_ERROR 表示錯誤
  • 非阻塞 Socket 需處理 WSAEWOULDBLOCK,配合 select/WSAEventSelect
  • 緩衝區大小 4KB-64KB 為宜,過小增加系統呼叫,過大浪費記憶體
  • 嚴格檢查 WSAStartup 版本協商結果,確保支援 2.2

掌握 socket → connect → send(HTTP GET) → recv 迴圈 核心模式,即可輕鬆實作各類 TCP 協議客戶端,奠定網路程式設計堅實基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved