<转>如何利用socket进行HTTP访问

原文:<转>如何利用socket进行HTTP访问

如何利用socket进行HTTP访问

平常我们要访问某个URL一般都是通过浏览器进行:提交一个URL请求后,浏览器将请求发向目标服务器或者代理服务器,目标服务器或者代理服务器返回我们所需要的数据,浏览器接收到这些数据后保存成文件并进行显示。

下面我们看看如何自己利用winsock2.h中的接口来实现这个功能?为了简化问题,作以下假设:

通过代理服务器进行HTTP访问,这样就省去了对URL进行DNS解析的步骤,假设代理服务器的地址为:192.168.0.1:808。

这个功能由以下几个部分组成:

1. 如何建立连接?

2. 如何发送请求?

3. 如何接收数据?

4. 如何判断数据接收完成?

下面我们依次来看下这些问题如何解决?

一、如何建立与服务器之间的连接

HTTP基本TCP,所以我们需要与服务器建立连接,然后才能发送数据。

建立连接参考如下函数socket_open:

/*

*打开Socket,返回socketId,-1表示失败

*/

int socket_open(int IP,int Port,int type){

SOCKET socketId;

struct sockaddr_in serv_addr;

int status;

socketId=socket(AF_INET,SOCK_STREAM,0);

if((int)socketId<0)

{

printf("[ERROR]Create a socket failed!/n");

return -1;

}

memset(&serv_addr,0,sizeof(serv_addr));

serv_addr.sin_family=AF_INET;

serv_addr.sin_addr.s_addr = ntohl(IP);

serv_addr.sin_port = htons((USHORT)Port);

status=connect(socketId,(struct sockaddr*)&serv_addr,sizeof(serv_addr));

if(status!=0)

{

printf("[ERROR]Connecting failed!/n");

closesocket(socketId);

return -1;

}

return socketId;

}

调用方式如下:

int socketId=socket_open(0xC0A80001,808,0); //0xC0A80001是192.168.0.1的十六进制写法。

二、如何发送请求

发送数据要根据HTTP协议的要求附加协议头:

static const char* protocolHead="GET http://www.xxx.com/index.html HTTP/1.1/n"

"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*/n"

"Accept-Language: zh-cn/n"

"User-Agent:iPanelBrowser/2.0/n"

"Host: www.xxx.com:80/n"

"Connection: close/n/n"

这里使用GET来获取指定URL的指定文档。

建立连接后使用send将这些数据发送出去:

send(socketId, protocolHead,strlen(protocolHead),0);

发送完成HTTP请求后就等待接收数据。

三、如何接收数据

这里采用select循环查询的方式来判断有无数据到来:

struct timeval tm = {0,7};

fd_set fds_r;

int status;

char recvBuf[4096]={‘/0’};

FD_ZERO(&fds_r);

FD_SET(socketId,&fds_r);

status=select(socketId+ 1, &fds_r, 0, 0, &tm); //socketId在这里是最大的fd

if(status > 0 && FD_ISSET(socketId, &fds_r))

{

printf("Socket is readable...fd=[%d]/n",socketId);

recv(socketId,recvBuf,4096,0);

}

这样数据包就保存到缓冲区中了。

四、如何判断数据接收完成

首先对返回数据的状态进行判断,仅当状态为“ HTTP 200 OK ”时才表明正确返回,这时才对数据进行解析并保存,如果状态为HTTP 404 NOT FOUND或者其它状态则表明没有找到资源或者出现其它问题,可参考HTTP 1.1状态代码及其含义

当数据正确返回时,为了将实际数据从协议中分离出来进行保存,需要对HTTP数据包进行解析得到Content-Length,然后在包含Content-Length的当前数据包或者随后的数据包中查找第一个空行,这就是内容(Content)的开始位置,再配合前面解析得到的Content-Length,就能够知道什么时候数据接收完成了。换行符为“/r/n”,也兼容“/n”或者“/r”,设换行符为^P,则空行如果位于内容中间或结尾则可查找“^P^P”,若位于开头,则查找^P。

基本就是上面这些,这四个问题解决了,那么整个问题也就解决了!

时间: 2024-10-08 02:51:45

<转>如何利用socket进行HTTP访问的相关文章

php 利用socket上传文件

php 利用socket上传文件 张映 发表于 2010-06-02 分类目录: php 一,利用fsockopen来上传文件 以前我写过一篇关于socket通信原理的博文http://blog.51yip.com/php/673.html有兴趣的朋友可以看看,前面讲的那篇博文,socket的服务器和客户端都是要用php命令来运行的.平常我们上传文件是浏览本地文件,通过一个php程序将文件上传一个地方,这个时候我们用php命令来运行php程序就不方便了.这个时候我们可以用fsockopen来打开

[python网络编程]利用socket编写简单的服务器

利用socket编写简单的服务器 步骤解析 建立socket对象 这一步跟我们上次使用socket做客户端是一样的,都需要有一个socket连接 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 设置socket选项(setsockopt) 选项介绍setsockopt(set socket option),参数设置格式:setsockopt(level,optname,value) 各选项的关系:1.level:level的设定决定了op

C++ 利用socket实现TCP,UDP网络通讯

学习孙鑫老师的vc++深入浅出,有一段时间了,第一次接触socket说实话有点儿看不懂,第一次基本上是看他说一句我写一句完成的,第二次在看SOCKET多少有点儿感觉了,接下来我把利用SOCKET完成TCP和UDP两种通讯模式的流程和代码分享一下,希望对大家多少能有点儿帮助,有什么说的不对的欢迎各位大神指正. TCP TCP是点对点的通讯模式,数据传输质量高,对于传输数据完整性要求高的情况一般用TCP,具体到vc++中,一般选用的是服务器/客户端模式,socket实现TCP通讯在服务器端一般分为以

利用IIS7 解决URL访问限制问题

网站可以通过URl直接访问一些不希望被访问的东西, 比如一些图片,js,css等等. 为了解决这个问题看了好多文章,不过毕竟我是新手菜鸟级别的,没有具体的解决方法,真心不知道怎么弄. 今天在看IIS的时候突然发现有一个叫"请求筛选"的东东,点击进入,发现里面可以配置筛选规则, 比如你可以自己添加 "拒绝文件扩展名",那么所有的符合你添加的那个文件扩展名的文件,都不能访问了. 具体: 打开IIS管理器--->点击你想要配置的网站,打开主页---->点击请求

【Jsp】利用Application对象实现访问人数统计功能

利用Application对象实现访问人数的统计很常见,但是一些书籍讲解这一技术的时候,往往没有做完整.一旦服务器重启,由于Application会被销毁,重新建立,人数统计则会再一次从零开始.解决方法,个人认为,应该同时利用到数据库,这样无论服务器要重启或者遭遇到停机什么,被统计的人数还是会一直累计上去,不会丢失.下面就介绍一个例子,解决利用Application对象实现访问人数统计功能由于服务器重启或者停机而导致从零开始的问题,同时介绍如果利用Application对象把保存到web.xml

利用socket进行消息推送

对于利用socket通信进行消息推送,我研究了两三天吧,当然是在前几天研究消息推送机制以及第三方和轮询的基础上进行的,以下是我的一些感想吧,有不正确或者不完善的地方希望大家提出来一起研究吧. 1.首先,了解socket的连接过程: 1)服务器监听:2)客户端请求:3)连接确认(具体详情可以见百度百科,我在这也就不多说了). 2.socket通信机制: 服务器端 一.创建服务器套接字(CREATE). 二.服务器套接字进行信息绑定(BIND),并开始监听连接(LISTEN). 三.接受来自客户端的

php 利用socket发送GET,POST请求

作为php程序员一定会接触http协议,也只有深入了解http协议,编程水平才会更进一步.最近我一直在学习php的关于http的编程,许多东西恍然大悟,受益匪浅.希望分享给大家.本文需要有一定http基础的开发者阅读. 今天给大家带来的是如何利用socket发送GET,POST请求.我借用燕十八老师封装好的一个Http类给进行说明. 在日常编程中相信很多人和我一样大部分时间是利用浏览器向服务器提出GET,POST请求,那么可否利用其它方式提出GET,POST请求呢?答案必然是肯定的.了解过HTT

利用socket模拟http的混合表单上传(在一个请求中提交表单并上传多个文件)

在很多企业级应用中,我们都没法直接通过开发语言sdk包封装的http工具来模拟http复合表单(multipart/form-data),特别是在跨语言跨平台的编程过程中,其实实现方案并不复杂,只要你了解了http协议中复合表单的报文结构就很简单了: httpheader ------时间戳------ 表单参数1 ------时间戳------ 表单参数2 ------时间戳------ 文件1的描述+二进制信息 ------时间戳------ 文件2的描述+二进制信息 下面我们进一步以一段c

自己动手写简单的web应用服务器(4)—利用socket实现文件的下载

直接上源码: 服务器: 1 package download; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.File; 6 import java.io.FileInputStream; 7 import java.io.IOException; 8 import java.io.OutputStream; 9 import java.net.Ser