您的位置:首页 > 理论基础 > 计算机网络

用C语言实现一个简单的HTTP客户端

2012-01-18 10:43 746 查看
用C语言实现一个简单的HTTP Client(HTTP客户端) (2007-04-17 21:32)

分类: 程序设计

http://blog.chinaunix.net/space.php?uid=11085590&do=blog&id=2914561

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 OK

Date: Tue, 03 Apr 2007 15:40:35 GMT

Server: Apache/2.0.55 (Unix)

Accept-Ranges: bytes

Vary: Accept-Encoding

Content-Length: 115440

Content-Type: text/html; charset=GB2312

Age: 176

X-Cache: HIT from www.163.com

Connection: close

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or

g/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; backgr

ound: #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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息