用C語言實現一個簡單的HTTP Client(HTTP用戶端)
作者:gobitan(雨水) 日期:2007-04-03 轉載請註明出處http://blog.csdn.net/gobitan HTTP協議是一個基於文本的協議,因此用C語言實現一個簡易的HTTP用戶端就不是什麼難事。但如果對這個不熟悉,要想一下子實現一個HTTP GET方法取擷取一個網頁這麼簡單的功能恐怕也未必是兩三分鐘能搞定的事。其關鍵是要理解HTTP協議的工作原理,具體參見RFC2616規範(http://www.ietf.org/rfc/rfc2616.txt);本文僅僅用一二十行代碼就實現了一個簡單的HTTP用戶端,它能夠將163的首頁擷取並列印出來。全部原始碼如下(httpClient.c),注意下面的程式是經過精簡的,很多參數直接寫入了程式,僅僅作為示範用。其中163伺服器位址是通過ping www.163.com 擷取到的,可能有變,測試時請靈活一點。只需修改“strcat(sndBuf, "Host: www.163.com/n/r/n");”和“ inet_addr("202.108.9.51");”就可以擷取其他地址的頁面。#include <stdio.h>#include "winsock2.h" #pragma comment(lib, "ws2_32.lib") int main(){ SOCKET sSocket = INVALID_SOCKET; SOCKADDR_IN stSvrAddrIn = {0}; /* 伺服器端地址 */ char sndBuf[1024] = {0}; char rcvBuf[2048] = {0}; char *pRcv = rcvBuf; int num = 0; int nRet = SOCKET_ERROR; WSADATA wsaData; /* HTTP 訊息構造開始,這是程式的關鍵之處 */ sprintf(sndBuf, "GET / HTTP/1.1/n"); strcat(sndBuf, "Host: www.163.com/n/r/n"); /* HTTP 訊息構造結束 */ /* socket DLL初始化 */ WSAStartup(MAKEWORD(2, 0), &wsaData); stSvrAddrIn.sin_family = AF_INET; stSvrAddrIn.sin_port = htons(80); stSvrAddrIn.sin_addr.s_addr = inet_addr("202.108.9.51"); sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* 串連 */ nRet = connect(sSocket, (SOCKADDR*)&stSvrAddrIn, sizeof(SOCKADDR)); if (SOCKET_ERROR == nRet) { printf("connect fail!/n"); return -1; } /* 發送HTTP請求訊息 */ send(sSocket, (char*)sndBuf, sizeof(sndBuf), 0); /* 接收HTTP響應訊息 */ while(1) { num = recv(sSocket, pRcv, 2048, 0); pRcv += num; if((0 == num) || (-1 == num)) { break ; } } /* 列印響應訊息 */ printf("%s/n", rcvBuf); return 0;} 本程式的最為關鍵是構建HTTP GET訊息。HTTP協議規範4.1小節中描述了HTTP訊息的格式,它包括一個起始行,零個或多個訊息頭,然後是空行(CRLF),最後是可選訊息體。示範程式中構建的HTTP訊息包含一個請求行(GET / HTTP/1.1)和一個訊息頭(Host: www.163.com)。如下兩行代碼:sprintf(sndBuf, "GET / HTTP/1.1/n");strcat(sndBuf, "Host: www.163.com/n/r/n");GET是HTTP的擷取方法,隨後的’/’表示擷取根目錄下的預設頁面,”HTTP/1.1”標明了協議及版本,注意後面的”/n”是必不可少的。下面一行是訊息頭,指明了擷取的主機,注意後面的”/n/r/n”,這個一定不能錯。空行CRLF就是用”/r/n”表示,這一點耗費了我很多時間,希望寫出來對大家有協助。本程式在Visual C++6.0環境下編譯通過並運行。直接執行程式,將列印出如下所示的擷取結果:HTTP/1.0 200 OKDate: Tue, 03 Apr 2007 15:40:35 GMTServer: Apache/2.0.55 (Unix)Accept-Ranges: bytesVary: Accept-EncodingContent-Length: 115440Content-Type: text/html; charset=GB2312Age: 176X-Cache: HIT from www.163.comConnection: close <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>網易</title><base target="_blank" /><meta name="Keywords" content="網易,新聞,體育,娛樂,女性,旅遊,文化,論壇,簡訊,數位,汽車,手機,財經,科技" /><meta name="Description" content="網易,新聞,體育,娛樂,女性,旅遊,文化,論壇,簡訊,數位,汽車,手機,財經,科技,專業報道門戶網站" /><meta name="robots" content="index, follow" /><meta name="googlebot" content="index, follow" /><style type="text/css"><!--/* CSS Document */body { text-align: center;"宋體", arial;margin:0; padding:0; background: #FFF; font-size:12px; color:#000;}div,form,img,ul,ol,li,dl,dt,dd {margin: 0; padding: 0; border: 0;}h1,h2,h3,h4,h5,h6 { margin:0; padding:0;}table,td,tr,th{font-size:12px;} /* 連結顏色 */a:link {color: #1f3a87; text-decoration:none;}a:visited {color: #83006f;text-decoration:none;}a:hover {color: #bc2931; text-decoration:underline;}a:active {color: #bc2931;}/* 顏色屬性 [定義規則,小寫c加?從上面的列印結果可以看出,163用的Apache伺服器,主機作業系統是Unix。
關於作者:胡家輝,網名:雨水 目前專註於XML文件管理及相關技術