原文:<转>如何利用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。
 
基本就是上面这些,这四个问题解决了,那么整个问题也就解决了!

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

  1. php 利用socket上传文件

    php 利用socket上传文件 张映 发表于 2010-06-02 分类目录: php 一,利用fsockopen来上传文件 以前我写过一篇关于socket通信原理的博文http://blog.51 ...

  2. 洗礼灵魂,修炼python(86)--全栈项目实战篇(12)—— 利用socket实现文件传输/并发式聊天

    由于本篇博文的项目都很简单,所以本次开个特例,本次解析两个项目,但是都很简单的 项目一:用socket实现文件传输 本项目很简单,作为小项目的预热的,前面刚学完socket,这里马上又利用socket ...

  3. 利用socket.io构建一个聊天室

    利用socket.io来构建一个聊天室,输入自己的id和消息,所有的访问用户都可以看到,类似于群聊. socket.io 这里只用来做一个简单的聊天室,官网也有例子,很容易就做出来了.其实主要用的东西 ...

  4. Java开发笔记(一百一十四)利用Socket传输文本消息

    前面介绍了HTTP协议的网络通信,包括接口调用.文件下载和文件上传,这些功能固然已经覆盖了常见的联网操作,可是HTTP协议拥有专门的通信规则,这些规则一方面有利于维持正常的数据交互,另一方面不可避免地 ...

  5. EBS中利用Socket与外系统通信

    某银行要求做一个签到签退功能,日终EBS系统发送报文与核心系统对帐,规定利用Socket来做传送,记录下步骤: 1.编辑: $INST_TOP/ora/10.1.3/j2ee/oacore/appli ...

  6. php 利用socket发送GET,POST请求

    作为php程序员一定会接触http协议,也只有深入了解http协议,编程水平才会更进一步.最近我一直在学习php的关于http的编程,许多东西恍然大悟,受益匪浅.希望分享给大家.本文需要有一定http ...

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

    学习孙鑫老师的vc++深入浅出,有一段时间了,第一次接触socket说实话有点儿看不懂,第一次基本上是看他说一句我写一句完成的,第二次在看SOCKET多少有点儿感觉了,接下来我把利用SOCKET完成T ...

  8. 在ASP.NET MVC3 中利用Jsonp跨域访问

    在ASP.NET MVC3 中利用Jsonp跨域访问 在信息系统开发的时,根据相关业务逻辑难免会多系统之间互相登录.一般情况下我们需要在多系统之间使用多个用户名和密码.这样客户就需要在多个系统之间重复 ...

  9. Java Socket聊天室编程(二)之利用socket实现单聊聊天室

    这篇文章主要介绍了Java Socket聊天室编程(二)之利用socket实现单聊聊天室的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 在上篇文章Java Socket聊天室编程(一)之 ...

随机推荐

  1. Android 建立View 圆角

    虽然很easy,不过还是录制. 混合参观 在drawable文件下 创建一个布局文件corners_bg.xml <?xml version="1.0" encoding=& ...

  2. 最艰难的采访IT公司ThoughtWorks代码挑战——FizzBuzzWhizz游戏

    最近的互联网招聘平台拉勾网在五月推出了"最艰难的采访IT公司"码挑战活动,评选出了5个最难面试的IT公司,即:ThoughtWorks.Google.Unisys.Rackspac ...

  3. 【Flume】flume于transactionCapacity和batchSize进行详细的分析和质疑的概念

    我不知道你用flume读者熟悉无论这两个概念 一开始我是有点困惑,? 没感觉到transactionCapacity的作用啊? batchSize又是干啥的啊? -- -- 带着这些问题,我们深入源代 ...

  4. Ubuntu14.04设备JDK

    1.设备JDK 打开命令直插式工具.输入以下三个命令: sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo ap ...

  5. boostrap-非常好用但是容易让人忽略的地方------input-group-btn

    1.正常的使用 <div class="form-group"> <div class="input-group"> <input ...

  6. ipset高大上性能果断将nf-HiPac逼下课

    netfilter.sourceforge,github上有一个凄凉的项目,那就是nf-hipac.这个以前给Linux firewall设计带来希望的项目早在2005年就停止了更新和维护,而我本人则 ...

  7. 10624 - Super Number

    题目链接 题意:给出n到m的范围,求出一个数在前i位数组成的数字能被i整除.假设存在输出这个数,假设不存在.输出-1. 思路:回溯,每次放第i位,然后推断是否符合题意.这题踩着时间过去的2.6s(看了 ...

  8. Android适配方案小结(一)

    相关计量单位介绍: px:是屏幕的像素点,不同设备显示的效果一样. in:英寸(1英寸等于2.54cm) mm:毫米 pt:磅, 1/72英寸 dp:device independent pixels ...

  9. HTML5 获得canvas油漆环境

    笔者:本笃庆军 原文地址:http://blog.csdn.net/qingdujun/article/details/32925369 我们用的最主要的画图环境在canvas中画图.通过调用canv ...

  10. 设计模式入门之装饰器模式Decorator

    //装饰模式定义:动态地给一个对象加入一些额外的职责. //就添加功能来说.装饰模式比生成子类更为灵活 //这也提现了面向对象设计中的一条基本原则,即:尽量使用对象组合,而不是对象继承 //Compo ...