zoukankan      html  css  js  c++  java
  • C++使用POST方法向网页提交数据-----C++发送HTTP数据获取Google天气预报

    例1:C++使用POST方法向网页提交数据    转自:http://www.it165.net/pro/html/201208/3534.html

    在C++中可以使用POST方法向网页中提交数据,这样就可以向类似论坛这样的网站注入垃圾帖子了。我的博客常常有海量的垃圾评论,大为恼火。
    为了不给其他人惹麻烦,就在本机测试。

    #include <iostream>
    #include <string>
    #include <afxinet.h> //定义了MFC CInternetSession类等
    
    bool PostHttpPage(const std::string& hostName,
                      const std::string& pathName,
                      const std::string& postData)
    {
     using namespace std;
    
     CInternetSession session("your app agent name");
    
     try
     {
       INTERNET_PORT nPort = 80;
       DWORD dwRet = 0;
    
       CHttpConnection* pServer = session.GetHttpConnection(
                                    hostName.c_str(),nPort);
       CHttpFile* pFile = pServer->OpenRequest(CHttpConnection::
                                    HTTP_VERB_POST,pathName.c_str());
    
       CString strHeaders = "Content-Type: application/x-www-form-
                                    urlencoded"; //请求头
    
       //开始发送请求
    
       pFile->SendRequest(strHeaders,(LPVOID)postData.c_str(),
       postData.size());
       pFile->QueryInfoStatusCode(dwRet);
    
       if (dwRet == HTTP_STATUS_OK)
       {
         CString result, newline;
    
         while(pFile->ReadString(newline))
         {//循环读取每行内容
           result += newline+"
    ";
         }
    
         std::cout<<result<<std::endl;//显示返回内容
       }
       else
       {
         return false;
       }
       delete pFile;
       delete pServer;
     }
     catch (CInternetException* pEx)
     {
        //catch errors from WinInet
        TCHAR pszError[200];
        pEx->GetErrorMessage(pszError, 200);
    
        std::cout<<pszError<<std::endl;//显示异常信息
        return false;
     }
     session.Close();
    
     return true;
    }
    
    int main(void)
    {
      //向本机Web目录下面的welcome.php页面发送发送
      PostHttpPage("localhost","welcome.php","name=rain&age=21");
    }

    在工程设计中,要选择-Use mfc in a shard dll 选项。
    在本机Web目录下面(就是Apache服务器配置文件中Directory配置的路径 ),存有welcome.php文件,当该文件收到post请求时,将请求的数据写入到文件中:

    <?php
     $file = fopen("./test.txt","w");
     fwrite($file,$_POST["name"]);
     fwrite($file,$_POST["age"]);
     fclose($file);
     ?>

    运行C++程序,在Web目录下面就会生成一个test.txt文本,文本的内容为rain21.

    例2:C++发送HTTP数据获取Google天气预报  转自:http://www.it165.net/pro/html/201208/3534.html

    工作一个星期了,基本都在看别人代码。现在主要看的是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
    ");
            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, '', BUFFSIZE_H);
        memset(host, '', BUFFSIZE_H);
        memset(GET, '', BUFFSIZE_H);
        memset(head, '', 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 != ''; ++phost);
        if ( (int)(phost - myurl) == strlen(myurl) )
            strcpy(GET, "/");
        else
            strcpy(GET, phost);
        *phost = ''; //> 相当于在www.google.com/的/位置替换为''.
        strcpy(host, myurl);//> 在www.google.com/的/位置为'',因此www.google.com被拷贝到&host.
        printf("%s
    %s
    ", host, GET);
    
        /*
        * 组织发送到web服务器的信息
        * 为何要发送下面的信息connect请参考HTTP协议的约定
        */
        strcat(head, "GET ");
        strcat(head, GET);
        strcat(head, " HTTP/1.1
    ");
        strcat(head, "host: ");
        strcat(head, host);
        strcat(head, "
    Connection: Close
    
    ");
        printf(head);
    
        if (SOCKET_ERROR == connect(sockeId, (SOCKADDR * )&addr, sizeof(addr)))
        {
            printf("connect failed!
    ");
            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!
    ");
            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, '', BUFFSIZE_H);
        FILE *fp;
        fp = fopen("whether.xml", "w+");
        if (NULL == fp)
        {
            printf("whether file create failed!
    ");
            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, '', 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
    " );
    
    
              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;
              }
    }
  • 相关阅读:
    研究SandHook
    MYSQL 事务与锁
    Java创造者詹姆斯·高斯林采访
    mybatis like 模糊查询
    【科普】彻底搞清楚什么是交换机什么是路由器。程序员基本功哦
    MinIO的简单使用实践
    如何将微信公众号的文章怎么保存转化为word文档?
    如何在recoil中主动刷新seloctor中缓存的值
    【译文】探索Recoil中的异步请求
    魅族云相册批量下载方案
  • 原文地址:https://www.cnblogs.com/hnfxs/p/3674920.html
Copyright © 2011-2022 走看看