• c++ 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! ");
           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! "); 
        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 "
         "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */* "
         "Accept-Language: zh-cn "
         "User-Agent:iPanelBrowser/2.0 "
         "Host: www.xxx.com:80 "
         "Connection: close "
         这里使用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]={‘’};
         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] ",socketId);
              recv(socketId,recvBuf,4096,0);
    }
     
    这样数据包就保存到缓冲区中了。
     
    四、如何判断数据接收完成
    首先对返回数据的状态进行判断,仅当状态为“ HTTP 200 OK ”时才表明正确返回,这时才对数据进行解析并保存,如果状态为HTTP 404 NOT FOUND或者其它状态则表明没有找到资源或者出现其它问题,可参考HTTP 1.1状态代码及其含义。
    当数据正确返回时,为了将实际数据从协议中分离出来进行保存,需要对HTTP数据包进行解析得到Content-Length,然后在包含Content-Length的当前数据包或者随后的数据包中查找第一个空行,这就是内容(Content)的开始位置,再配合前面解析得到的Content-Length,就能够知道什么时候数据接收完成了。换行符为“ ”,也兼容“ ”或者“ ”,设换行符为^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 Host: 192.168.1.12 Connection: Close ";
    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访问”的更多相关文章 》

  • 相关阅读:
    低级错误之Hbm中类型不一致错误
    低级错误之Oracle客户端添加数据
    低级错误之页面中action的请求地址与action中写的requsetmapping不一致
    低级错误之删除存在关联的表报错
    低级错误之方法自调陷入死循环
    Notepad++的一些常用的快捷键
    [css]inline-block
    框架开发之Java注解的妙用
    面试必备【含答案】Java面试题系列(二
    Kotlin:数组、字符串模板
  • 原文地址:https://www.cnblogs.com/zzyoucan/p/5006904.html
Copyright © 2020-2023  润新知