平常我们要访问某个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,&amp;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。
 
基本就是上面这些,这四个问题解决了,那么整个问题也就解决了!
文章出处:DIY部落(http://www.diybl.com/course/3_program/c++/cppsl/2008227/101925.html)

另外一个帖子

c socket 发送http请求
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(){
int sockfd;
int len;
struct sockaddr_in address;
int result;
char *strings="GET /svnup/rewrite.php HTTP/1.1\r\nHost: 192.168.1.12\r\nConnection: Close\r\n\r\n";
char ch;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("192.168.1.12");
address.sin_port = htons(80);
len = sizeof(address);
result = connect(sockfd,  (struct sockaddr *)&address, len);
if(result == -1){
    perror("oops: client1");
    return 1;
}
write(sockfd,strings,strlen(strings));
while(read(sockfd,&ch,1))
    printf("%c", ch);
close(sockfd);
return 1;
}

“如何利用socket进行HTTP访问”的更多相关文章 》

c++ http请求的更多相关文章

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  2. Android请求网络共通类——Hi_博客 Android App 开发笔记

    今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...

  3. 重温Http协议--请求报文和响应报文

    http协议是位于应用层的协议,我们在日常浏览网页比如在导航网站请求百度首页的时候,会先通过http协议把请求做一个类似于编码的工作,发送给百度的服务器,然后在百度服务器响应请求时把相应的内容再通过h ...

  4. Taurus.MVC 2.2 开源发布:WebAPI 功能增强(请求跨域及Json转换)

    背景: 1:有用户反馈了关于跨域请求的问题. 2:有用户反馈了参数获取的问题. 3:JsonHelper的增强. 在综合上面的条件下,有了2.2版本的更新,也因此写了此文. 开源地址: https:/ ...

  5. nodejs之get/post请求的几种方式

    最近一段时间在学习前端向服务器发送数据和请求数据,下面总结了一下向服务器发送请求用get和post的几种不同请求方式: 1.用form表单的方法:(1)get方法 前端代码: <form act ...

  6. ajax异步请求

    做前端开发的朋友对于ajax异步更新一定印象深刻,作为刚入坑的小白,今天就和大家一起聊聊关于ajax异步请求的那点事.既然是ajax就少不了jQuery的知识,推荐大家访问www.w3school.c ...

  7. C# MVC 5 - 生命周期(应用程序生命周期&请求生命周期)

    本文是根据网上的文章总结的. 1.介绍 本文讨论ASP.Net MVC框架MVC的请求生命周期. MVC有两个生命周期,一为应用程序生命周期,二为请求生命周期. 2.应用程序生命周期 应用程序生命周期 ...

  8. nodejs进阶(5)—接收请求参数

    1. get请求参数接收 我们简单举一个需要接收参数的例子 如果有个查找功能,查找关键词需要从url里接收,http://localhost:8000/search?keyword=地球.通过前面的进 ...

  9. 无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查。。。

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 无法向会话状态服务器发出会话状态请求.请确保 ASP.NET State Ser ...

  10. [转]利用URLConnection来发送POST和GET请求

    URL的openConnection()方法将返回一个URLConnection对象,该对象表示应用程序和 URL 之间的通信链接.程序可以通过URLConnection实例向该URL发送请求.读取U ...

随机推荐

  1. linux 配置 crontab

    linux中的crontab是定时用的,下面的cron服务就是定时器的意思 crontab -l 列举所有的cron服务 crontab -e 修改cron服务 crontab -r 删除cron服务 ...

  2. iOS开发--换肤简单实现以及工具类的抽取

    一.根据美工提供的图片,可以有两种换肤的方案. <1>美工提供图片的类型一: <2>美工提供图片的类型二:这种分了文件夹文件名都一样的情况,拖入项目后最后用真实文件夹(蓝色文件 ...

  3. 【codevs 1565】【SDOI 2011】计算器 快速幂+拓展欧几里得+BSGS算法

    BSGS算法是meet in the middle思想的一种应用,参考Yveh的博客我学会了BSGS的模版和hash表模板,,, 现在才会hash是不是太弱了,,, #include<cmath ...

  4. DOS常用命令收集(长期更新)

    命令列表 命令 说明 ASSOC 显示或修改文件扩展名关联. ATTRIB 显示或更改文件属性. BREAK 设置或清除扩展式 CTRL+C 检查. BCDEDIT 设置启动数据库中的属性以控制启动加 ...

  5. 【深入Java虚拟机】之二:Java垃圾回收机制

    [深入Java虚拟机]之:Java垃圾收集机制 对象引用 Java中的垃圾回收一般是在Java堆中进行,因为堆中几乎存放了Java中所有的对象实例.谈到Java堆中的垃圾回收,自然要谈到引用.在JDK ...

  6. OO(Object Oriented)思想和PO(Procedure-Oriented)思想

    对象将需求用类一个个隔开,就象用储物箱把东西一个个封装起来一样,需求变了,分几种情况,最严重的是大变,那么每个储物箱都要打开改,这种方法就不见得有好处:但是这种情况发生概率比较小,大部分需求变化都是局 ...

  7. 又爱又恨系列之枚举enum

    其实枚举挺简单的,只不过以前没好好学,所以不知道这个东西,恩,现在梳理一下 整体而言,首先枚举是一个数据类型,这个数据类型和结构体有点像 可以分为三个层次 1.枚举数据类型定义 第一种:enum 枚举 ...

  8. Java多线程与并发库高级应用-Callable与Future的应用

    Callable这种任务可以返回结果,返回的结果可以由Future去拿 >Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的. >Completion ...

  9. 操蛋的CTex

    我一向是不屑于在windows下用latex的,看起来不伦不类,是geek就不要用windows,图方便就用word而不是latex.但是台式机上的fedora无法上网,那就委屈一下在windows1 ...

  10. 【BZOJ-1097】旅游景点atr SPFA + 状压DP

    1097: [POI2007]旅游景点atr Time Limit: 30 Sec  Memory Limit: 357 MBSubmit: 1531  Solved: 352[Submit][Sta ...