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

網頁刷新器實戰:域名解析、HTTP GET 與完整響應接收

     編輯:關於C語言

網頁刷新器

從簡易客戶端到通用刷新器

上一篇的簡易客戶端存在三大短板:僅支持 IP 直連、硬編碼單一 URL、單次 recv 截斷長響應。本文實現通用網頁刷新器,解決這三問題:

  • 支持域名參數化,運行時經 gethostbyname() 解析
  • URL 路徑作為命令行參數傳入
  • 循環 recv() 直到對端關閉,完整接收響應

核心代碼實現

#include <comlib.h>  // 假設項目通用庫

// HTTP GET 請求模板(雙 %s 分別佔位 路徑、Host)
char req_tmpl[] =
    "GET %s HTTP/1.0\r\n"
    "Accept: */*\r\n"
    "Accept-Language: zh-cn\r\n"
    "Accept-Encoding: gzip, deflate\r\n"
    "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)\r\n"
    "Host: %s\r\n"
    "Connection: Keep-Alive\r\n\r\n";

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s  \n", argv[0]);
        return 1;
    }

    char *host = argv[1];        // 如 www.example.com
    char *path = argv[2];        // 如 /vote.asp?id=1001

    // 1. 域名解析
    struct hostent *he = gethostbyname(host);
    if (!he) { herror("gethostbyname"); return 2; }
    char *ip = inet_ntoa(*(struct in_addr*)he->h_addr);
    fprintf(stderr, "Resolved IP: %s\n", ip);

    // 2. 建立 TCP 連接(端口 80)
    int sock;
    ASSERT(ConnectSock(&sock, 80, ip) == 0); // 假設通用庫封裝

    // 3. 組裝並發送請求
    char req[2048];
    sprintf(req, req_tmpl, path, host); // 關鍵:格式化字符串可為變量
    WriteFile(sock, req, strlen(req));
    fprintf(stderr, ">>> Request sent:\n%s", req);

    // 4. 循環完整接收響應
    char buf[1024];
    int total = 0, n;
    while ((n = recv(sock, buf, sizeof(buf), 0)) > 0) {
        fwrite(buf, 1, n, stderr); // 直接輸出到 stderr 觀察
        total += n;
    }
    fprintf(stderr, "\n<<< Total received: %d bytes\n", total);

    close(sock);
    return 0;
}

編譯與運行示例

# 編譯(鏈接自定義 comlib)
cc -o http2 http2.c -O -DUNIX -DDEBUG -DTRACE_FILE='"./trace"' \
   -I/u/zyx/code/comlib/include -L/u/zyx/code/comlib/lib -lcom

# 實戰 1:新浪遊戲投票(模擬瀏覽器投票)
./http2 publish.games.sina.com.cn "/poll.php?p_id=560&t_id=1327"

# 實戰 2:訪問任意網站首頁
./http2 www.csai.cn /

關鍵技術點解析

1. sprintf 格式化字符串變量化

sprintf(buf, buf2, argv[2], argv[1]) 中 buf2 是變量而非字面量,C 標準完全支持,極大提升模板復用靈活性。

2. 循環 recv 保證完整性

HTTP/1.0 默認 Connection: Close,服務器發送完數據主動關閉連接,客戶端 recv 返回 0 表示接收結束。對於 Keep-Alive 或 Chunked 編碼,需解析 Content-Length 或分塊結束標記。

3. 錯誤處理最小集

  • gethostbyname 失敗 → herror 輸出詳細 DNS 錯誤
  • ConnectSock 斷言失敗 → 終止程序
  • recv 返回 -1 → 檢查 errno 區分中斷/超時/連接重置

安全與道德提醒

本工具僅供學習 Socket 編程、HTTP 協議、域名解析之用。 請勿用於壓力測試、惡意刷流量、暴力破解等違法行為。任何對目標服務器造成損害的使用均與作者無關,使用者自負法律責任。

進階擴展方向

  • 支持 HTTPS(集成 OpenSSL)
  • 解析響應頭提取 Content-Length、Set-Cookie、Location 等關鍵信息
  • 實現重定向自動跟隨(301/302)
  • 添加命令行選項:自定義 Header、POST 數據、代理支持、超時控制
  • 構建為庫函數 http_get(host, path, headers, timeout, &resp) 供其他模塊調用

掌握這個刷新器核心模型,你已具備開發爬蟲、API 客戶端、監控探針、自動化測試工具的基因。

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