例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+"\r\n";
     }

     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\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;
          }
}