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

摘要:
但是,如果您不熟悉这一点,那么实现HTTPGET方法这样的简单函数访问网页可能不需要两三分钟。关键是理解HTTP协议的工作原理,详见RFC2616规范;在本文中,一个简单的HTTP客户端仅用20行代码实现,它可以获取并打印163的主页。HTTP协议规范第4.1节描述了HTTP消息的格式,其中包括一个起始行、零个或多个消息头,然后是一个空行,最后是一个可选的消息体。演示中内置的HTTP消息包含请求行和消息头。

用C语言实现一个简单的HTTP客户端(HTTP Client) - 雨水的专栏 - 博客频道 - CSDN.NET


分类:
2. C/C++语言

2007-04-03 23:30
4632人阅读
评论(4)
收藏
举报

用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 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。

免责声明:文章转载自《用C语言实现一个简单的HTTP客户端(HTTP Client)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇PHP的openssl加密扩展使用小结PCB设计规则中英文对照下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C语言刷 堆(优先队列)

703. 数据流中的第 K 大元素 /* 小根堆 */ typedef struct { int heapCapacity; int heapSize; int *heap; } KthLargest; /* 堆顶下标: 0; parent: (k-1)/2; leftChild: 2*k + 1; rightChild: 2*k...

C语言分配4k对齐内存

分配内存,按4k字节对齐。亦即分配的内存指针指向的地址,低12位(二进制)均为0。 假设要分配size字节内存。基本思路就是先分配size+4k-1字节的内存,然后在起始的4k字节里,找到4k对齐的那个地址(即低12位为0),作为对齐内存首地址,返回。 当然为了避免内存泄漏,要保留初始分配的内存地址,在使用完内存后,需要free掉分配的所有内存。 #inc...

C语言-枚举 enum,typedef

目录 枚举 枚举的注意事项 使用规范 typedef 枚举 请声明一个变量保存一个人的性别 ,一个人的学历,一个方向,这样用 char 类型是不是不能全部给保存下,性别有男女两个值,但是你定义一个也只能保存一个值 某些变量的取值是限定的,变量的取值只能是指定的几个值当中的任意一个,除此之外的不行 C语言没有提供那么我就自己定义一个限定取值的类...

c语言运算符

1.运算符概述 运算符是一种编译器执行特定的数学或逻辑操作的符号。C语言提供了以下类型的运算符: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 条件运算符 其他运算符 2.算术运算符 算术运算符分为单目运算符和双目运算符,单目运算符表示只需要一个操作数,双目运算符需要两个操作数。 2.1 双目算术运算符 1)+ :加法,把两个操作数相加...

C/C++常用库及工具

值得学习的C语言开源项目 - 1. Webbench  Webbench是一个在Linux下使用的非常简单的网站压测工具。它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力。Webbench使用C语言编写, 代码实在太简洁,源码加起来不到600行。 下载链接:http://...

TIOBE 四月世界编程语言排行榜:C语言重回榜首

TIOBE 2012年4月世界编程语言排行榜已经发布。C语言超越了Java重回榜首;而Objective-C则一路飙升,超越了C#,占据了第4的位置;并且C++也重新回到第3的位置。而Python持续下滑,目前排名第8。 TIOBE2012年4月世界编程语言排行榜的前20名 从开发领域来讲,只要有合适的硬件驱动和API,C或者C++理论上是可以做任何开发的...