原文:<转>如何利用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. JTree

    http://www.easyicon.net/ package swing.tree; import java.awt.BorderLayout; import java.awt.Component ...

  2. 二元最近的共同祖先问题(O(n) time 而且,只有一次遍历,O(1) Space (它不考虑函数调用栈空间))

    问题: 找到两个节点的二叉树的最近的共同祖先. 首先可以参考这个博客http://blog.csdn.net/cxllyg/article/details/7635992 ,写的比較具体,包含了节点包 ...

  3. 高性能mysql主存架构

    原文:高性能mysql主存架构 MySQL Replication(Master与Slave基本原理及配置) 主从mysql工作原理: 1:过程: (1)Mysql的复制(replication)是一 ...

  4. SQL Server 2005------函数

    原文:SQL Server 2005------函数 SQL Server 2005支持用户自定义函数和内置系统函数,根据返回值类型又分为标量函数和表值函数. 1.标量函数标量函数:返回单个数据值,返 ...

  5. atitit.基于组件的事件为基础的编程模型--服务器端控件(1)---------服务器端控件和标签之间的关系

    atitit.基于组件的事件为基础的编程模型--服务器端控件(1)---------服务器端控件和标签之间的关系 1. server控件是要server了解了标签.种类型的server控件: 1 1. ...

  6. MVC把随机产生的字符串转换为图片

    原文:MVC把随机产生的字符串转换为图片 Insus.NET在这篇中<在ASP.NET MVC应用程序中随机获取一个字符串>http://www.cnblogs.com/insus/p/3 ...

  7. 它们的定义UIAlertView

    code4App有很多伟大的上方UI特效代码,,好牛逼啊,这效果,太炫了,哇,怎么自己写不出来.事实上,再炫的特效,都是依据苹果系统的框架而来,假设我们了解系统框架实现的原理,也就能写出属于自己自己定 ...

  8. Leetcode 动态规划 Candy

    本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie Candy Total Accepted: 16494 Total Submissions: ...

  9. Linux对于录音

    一.原理简介 在Linux下,记录--从dsp读取数据.播放--至dsp设备写入数据. 开发板採用声卡UDA1341实现音频编解码,完毕A/D和D/A转换,芯片UDA1341与CPU的连接图例如以下: ...

  10. What is WCF

    几个博客前,都是关于WCF零散的知识.要了解下下面的宏,什么是WCF? WCF:Windows Communication Foundation(WCF)框架. 1.WCF体系框架 2.框架分析 2. ...