• 热门专题

C++发送HTTP数据获取Google天气预报

作者:HuangLei_LEGO博客  发布日期:2012-08-20 09:03:19
Tag标签:发送HTTP  Google天气预报  
  • 工作一个星期了,基本都在看别人代码。现在主要看的是Http部分的,不断和服务器交互,不断得到反馈信息或者提交信息。诸如此类,因此为了加深C对Http的处理,还是稍微练习下或者说了解和实验下,俗话说“好记性不如烂笔头”,厉害的人都是靠学习来的。

       在Windows下利用C语言进行http请求,想google天气API发送请求获取数据并保存!以下是工程文件:

    各个文件代码:
    //> downdata.h


    #ifndef DOWNDATA_H_INCLUDED
    #define DOWNDATA_H_INCLUDED
    
    
    #define BUFFSIZE_H 1024
    
    
    #ifdef __cpluscplus
    extern "C"
    {
    #endif
    
    
    /**
    * @brief 向网络请求资源,返回值存储到当前目录的临时文件whether.txt中.
    * @param pUrl - 请求的URL.
    * @return if get data return true, else if get nothing return false.
    */
    bool WEBQuest(const char * pUrl);
    
    
    #ifdef __cpluscplus
    }
    #endif
    
    
    #endif // DOWNDATA_H_INCLUDED
    

    //> downdata.cpp
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    //#include "windows.h"
    #include "winsock2.h"
    
    #include "downdata.h"
    #include "freeptr.h"
    
    #pragma comment(lib, "ws2_32.lib") //在某些编译器下,需要添加编译参数到工程设置中,比如CodeBlocks(这样,这行就不需要了).
                                                                          //Code::blocks 中新建一个工程, 然后右击工程
                                                                          //选择 build options
                                                                          //选择Linker setting
                                                                          //在 Other linker options 中添加: -lwsock32
    /**
    * @brief 为了加深http的理解和数据相关的操作,实现之.
    */
    bool WEBQuest(const char * pUrl)
    {
    #if 1   //no this declaration, socket create failed.
        WSADATA WsaData;
    
        if (WSAStartup(MAKEWORD(2,2),&WsaData))
        {
            printf("The socket failed");
            return false;
        }
    #endif
    
        SOCKET sockeId;
        SOCKADDR_IN addr;
    
        if (-1 == (sockeId = socket(AF_INET, SOCK_STREAM, 0)))
        {
            printf("socket create failed\n");
            return false;
        }
    
        //> dest_addr
        addr.sin_addr.S_un.S_addr = inet_addr("74.125.71.105"); //> googleIP,可以用IP地址查询得到
        addr.sin_family = AF_INET;
        addr.sin_port = htons(80);
    
        //> request_url
        /* www.it165.net
        * 分离url中的主机地址和相对路径
        */
        char *phost = 0;
        char * myurl = (char * ) malloc (BUFFSIZE_H * sizeof(char));
        char * host = (char * ) malloc (BUFFSIZE_H * sizeof(char));
        char * GET =  (char * ) malloc (BUFFSIZE_H * sizeof(char));
        char * head =(char * ) malloc(BUFFSIZE_H * sizeof(char));
        memset(myurl, '\0', BUFFSIZE_H);
        memset(host, '\0', BUFFSIZE_H);
        memset(GET, '\0', BUFFSIZE_H);
        memset(head, '\0', BUFFSIZE_H);
    
        //> pUrl - www.google.com/ig/api?hl=zh_cn&weather=beijing
        //> www.google.com - &host
        //> /ig/api?hl=zh_cn&weather=beijing - &GET
        strcpy(myurl, pUrl);
    
        for (phost = myurl; *phost != '/' && *phost != '\0'; ++phost);
        if ( (int)(phost - myurl) == strlen(myurl) )
            strcpy(GET, "/");
        else
            strcpy(GET, phost);
        *phost = '\0'; //> 相当于在www.google.com/的/位置替换为'\0'.
        strcpy(host, myurl);//> 在www.google.com/的/位置为'\0',因此www.google.com被拷贝到&host.
        printf("%s\n%s\n", host, GET);
    
        /*
        * 组织发送到web服务器的信息
        * 为何要发送下面的信息connect请参考HTTP协议的约定
        */
        strcat(head, "GET ");
        strcat(head, GET);
        strcat(head, " HTTP/1.1\r\n");
        strcat(head, "host: ");
        strcat(head, host);
        strcat(head, "\r\nConnection: Close\r\n\r\n");
        printf(head);
    
        if (SOCKET_ERROR == connect(sockeId, (SOCKADDR * )&addr, sizeof(addr)))
        {
            printf("connect failed!\n");
            closesocket(sockeId);
            WSACleanup();
    #if 0
            free(myurl);
            free(host);
            free(GET);
            free(head);
            myurl = NULL;
            host = NULL;
            GET = NULL;
            head = NULL;
    #endif
              freeCharPtr(&myurl, &host, &GET, &head, NULL);
    
            return false;
        }
    
        if (SOCKET_ERROR == send(sockeId, head, strlen(head), 0))
        {
            printf("send &header error!\n");
            closesocket(sockeId);
            WSACleanup();
    #if 0
            free(myurl);
            free(host);
            free(GET);
            free(head);
            myurl = NULL;
            host = NULL;
            GET = NULL;
            head = NULL;
    #endif
              freeCharPtr(&myurl, &host, &GET, &head, NULL);
    
            return false;
        }
    
        memset(head, '\0', BUFFSIZE_H);
        FILE *fp;
        fp = fopen("whether.xml", "w+");
        if (NULL == fp)
        {
            printf("whether file create failed!\n");
            closesocket(sockeId);
            WSACleanup();
    #if 0
            free(myurl);
            free(host);
            free(GET);
            free(head);
            myurl = NULL;
            host = NULL;
            GET = NULL;
            head = NULL;
    #endif
              freeCharPtr(&myurl, &host, &GET, &head, NULL);
    
            return false;
        }
        while (recv(sockeId, head, BUFFSIZE_H, 0) > 0)
        {
            fputs(head, fp);
            memset(head, '\0', BUFFSIZE_H);
        }
         #if 0
        free(myurl);
        free(host);
        free(GET);
        free(head);
        myurl = NULL;
        host = NULL;
        GET = NULL;
        head = NULL;
    #endif
         freeCharPtr(&myurl, &host, &GET, &head, NULL);
        closesocket(sockeId);
        WSACleanup();
    
        return true;
    }
    
    

    //> main.cpp

    #include <iostream> //> system
    #include <stdio.h>
    #include "downdata.h"
    using namespace std;
    
    
    int main(void )
    {
         if (!WEBQuest("www.google.com/ig/api?hl=zh_cn&weather=beijing" ))
        {
            return -1;
        }
        printf( "Whether have been writtend to file whether.xml\n" );
    
    
              system( "pause");
               return 0;
    }
    

    //> 关于内存释放,自己封装了一个变参形式的(char *参数)释放函数
    //> freeptr.h
    #ifndef FREEPTR_H
    #define FREEPTR_H
    
    
    #ifdef __cpluscplus
    extern "C"
    {
    #endif
    
    
    void freeCharPtr(char ** ch, ...);
    
    
    #ifdef __cpluscplus
    }
    #endif
    #endif
    

    //> freeptr.cpp
    #include <stdlib.h>
    #include <stdarg.h>
    #include "freeptr.h"
    
    
    void freeCharPtr(char ** ch, ...)
    {
              va_list ap;
               char **  p;
              
              va_start(ap, ch);
              free(*ch);
              *ch = NULL;
               while (p = va_arg(ap, char ** ))
              {
                       free(*p);
                       *p = NULL;
              }
    }
    
    

延伸阅读:

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规