curl的使用实例 cpp封装

来源:互联网 发布:vscode .net core 编辑:程序博客网 时间:2024/05/16 09:29

http://blog.chinaunix.net/uid-20384806-id-1954334.html


 curl的使用实例 cpp封装 2009-06-09 15:03:22

分类: C/C++

关于curl的基本用法请见curl的官网(http://curl.haxx.se/) 以及我的前一篇转载别人的博文:http://blog.chinaunix.net/u/16292/showart_1951736.html 。

本文给出一个 curl 的简单 c++ 封装类,以及测试用例。

头文件:

/**
 * @file HCUrl.h
 *
 * @brief
 * The CCUrl class header file.</br>
 *
 * @author zieckey
 *
 * @date Jun. 3 2009
 *
 * @version 0.0.1
 *
 * Revision History
 * @if CR/PR ID Author    Date    Major Change @endif
 * @bug \n
****************************************************************************/


#ifndef __CCUrl_H__
#define __CCUrl_H__

#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>

#include <string.h>

namespace OSLib
{
    //const long CLIENTTIMEOUT = 10;


    /*! @class CCUrl CCUrl.h "CCUrl.h"
    * @brief This is the CCUrl class, a wrapper of libcurl.
    *
    */

    class CCUrl
    {
    public:
        CCUrl();
        virtual ~CCUrl();
    
        /**
        * @brief <b>Summary:</b>
        *    Initiate this CURL session
        * @return    0, if success. <br>
        *            -1, if failed.
        *******************************************************************************/

        int    init();
    
    protected:
        /**
        * @brief <b>Summary:</b>
        *        This function is virtual function, which will be called by automatic, 
        *    as soon as there is data received that needs to be processed.<br>
        *        The size of the data pointed to by 'data' is 'size' multiplied with 'nmemb', 
        *    it will not be zero terminated. <br>
        * @note    You should override this function to do you own busyness. 
        *        You save the data to a file, or process it anyway.
        * @param[in] data, point to the data
        * @param[in] size, the size        
        * @param[in] nmemb, the unit in bytes        
        * @return 
        *****************************************************************************/

        virtual int process( void* data, size_t size, size_t nmemb );

    public:
        /**
        * @brief <b>Summary:</b>
        *    Post 'data' to 'url', and the server response data is restored in resultData.
        *    The process function is 'pfun' 
        * @param[in]    url
        * @param[in]    data, the data to be sent to server. 
        *                    eg. "id=admin&passwd=123456"
        * @param[in]    timeout, the limit time in seconds to do this process.
        *                    default value 10
        * @param[in]    withheader, 
        *                    1 indicate the server response data including header
        *                    0 indicate the server response data excluding header
        *                    default value 0
        * @return    0, if success. </br>
        *            -1, if failed.
        *******************************************************************************/

        int doHttpPost( const char* url, const char* data, long timeout = 10, long withheader = 0 );

        /**
        * @brief <b>Summary:</b>
        *    Get 'url' using 'data' to be set in the header, 
        *    and the server response data is restored in resultData.
        *    The process function is 'pfun' 
        * @param[in]    url
        * @param[in]    data, the data to be sent to server. 
        *                    eg. "id=admin&passwd=123456"
        * @param[in]    timeout, the limit time in seconds to do this process.
        *                    default value 10
        * @param[in]    withheader, 
        *                    1 indicate the server response data including header
        *                    0 indicate the server response data excluding header
        *                    default value 0
        * @return    0, if success. </br>
        *            -1, if failed.
        *******************************************************************************/

        int doHttpGet( const char* url, const char* data, long timeout = 10, long withheader = 0 );


    public:
        //CURLcode setOpt( CURLoption option ); 


        /**
        * @brief <b>Summary:</b>
        *    Reset all options of a libcurl session handle
        * @return void, no return
        *******************************************************************************/

        void resetOpt(); 
        
    private:
        /**
        * @brief <b>Summary:</b>
        *        This function gets called by libcurl as soon as there is data received
        *    that needs to be saved.<br>
        *        The size of the data pointed to by ptr is size multiplied with nmemb, 
        *    it will not be zero terminated. <br>
        * @param[in] 
        * @param[in]    
        * @param[in]    
        * @param[in] usrptr, the user ptr, 
        *            set by option CURLOPT_READDATA or CURLOPT_WRITEDATA...
        * @return    the number of bytes actually taken care of. <br>
        *        If that amount differs from the amount passed to your function,
        *    it'll signal an error to the library and it will abort the transfer 
        *    and return CURLE_WRITE_ERROR. 
        *****************************************************************************/

        static size_t processFunc( void* ptr, size_t size, size_t nmemb, void *usrptr );

    private:
        CURL * m_curl;
    };    
};

#endif

实现文件:

#include "HCUrl.h"

namespace OSLib
{

    CCUrl::CCUrl() : m_curl(NULL)
    {
    }
    
    CCUrl::~CCUrl()
    {
        ::curl_easy_cleanup( m_curl ); 
        ::curl_global_cleanup(); 
    }

    int CCUrl::init()
    {
        CURLcode res = ::curl_global_init( CURL_GLOBAL_ALL );
        if( CURLE_OK != res ) 
        {
            fprintf( stderr, "curl_global_init failed: %d \n", res ); 
            return -1;
        }
    
        m_curl = ::curl_easy_init(); 
        if( NULL == m_curl )
        {
            fprintf( stderr, "curl_easy_init failed\n" ); 
            return -1;
        }
        return 0;
    }


    int CCUrl::doHttpPost( const char* url, const char* data, long timeout, long withheader )
    {
        resetOpt();
        ::curl_easy_setopt( m_curl, CURLOPT_HEADER, withheader );
        ::curl_easy_setopt( m_curl, CURLOPT_URL, url );
        ::curl_easy_setopt( m_curl, CURLOPT_POST, 1 );
        ::curl_easy_setopt( m_curl, CURLOPT_POSTFIELDS, data );
        ::curl_easy_setopt( m_curl, CURLOPT_TIMEOUT, timeout );
        ::curl_easy_setopt( m_curl, CURLOPT_WRITEFUNCTION, CCUrl::processFunc ); 
        ::curl_easy_setopt( m_curl, CURLOPT_WRITEDATA, this );
        CURLcode res = ::curl_easy_perform( m_curl);
        return ( 0 == res ) ? 0 : -1;
    }

    int CCUrl::doHttpGet( const char* url, const char* data, long timeout, long withheader )
    {
        resetOpt();
        size_t urllen = strlen( url );
        size_t datalen = strlen( data );
        char* surl = new char[ urllen + datalen + 1 + 1];
        if( !surl )
        {
            fprintf( stderr, "doHttpGet failed, unable to malloc memery\n" ); 
            return -1;
        }
        strncpy( surl, url, urllen );
        surl[ urllen ] = '?';
        strcpy( surl + urllen + 1, data );
        ::curl_easy_setopt( m_curl, CURLOPT_URL, surl );
        ::curl_easy_setopt( m_curl, CURLOPT_HTTPGET, 1 );
        ::curl_easy_setopt( m_curl, CURLOPT_HEADER, withheader );
        ::curl_easy_setopt( m_curl, CURLOPT_TIMEOUT, timeout );
        ::curl_easy_setopt( m_curl, CURLOPT_WRITEFUNCTION, CCUrl::processFunc ); 
        ::curl_easy_setopt( m_curl, CURLOPT_WRITEDATA, this ); 

        CURLcode res = ::curl_easy_perform( m_curl);

        delete [] surl;
        return ( 0 == res ) ? 0 : -1;
    }

    void CCUrl::resetOpt()
    {
        ::curl_easy_reset( m_curl );
        //::curl_easy_setopt( m_curl, CURLOPT_VERBOSE, 1 );//set this to show debug message

    }

    size_t CCUrl::processFunc( void* ptr, size_t size, size_t nmemb, void *usrptr )
    {
        CCUrl* p =(CCUrl*) usrptr;
        return p->process( ptr, size, nmemb );
    }
    


    int CCUrl::process( void* data, size_t size, size_t nmemb ) 
    {
        printf( "\n ===== CCUrl::process( void* data, size_t size, size_t nmemb ) ===== \n" ); 
        return size * nmemb; 
    }

//     int CCUrl::uploadFile( const char* url, const char* localfilename )

//     {

//         m_upfilename = (char*)localfilename;

//         resetOpt();

//         ::curl_easy_setopt( m_curl, CURLOPT_URL, url );/**<Upload to this url place*/

//         ::curl_easy_setopt( m_curl, CURLOPT_UPLOAD, 1 );

//         ::curl_easy_setopt( m_curl, CURLOPT_READFUNCTION, CCUrl::uploadFileReadFunc ); 

//         ::curl_easy_setopt( m_curl, CURLOPT_READDATA, this ); 

//         CURLcode res = ::curl_easy_perform( m_curl);

//         return ( 0 == res ) ? 0 : -1;

//     }

//

//     size_t CCUrl::uploadFileReadFunc( void* ptr, size_t size, size_t nmemb, void *usrptr )

//     {

//         CCUrl* p =(CCUrl*) usrptr;

//         static FILE* pf = NULL;

//         if( !pf ) 

//         {

//             pf = fopen( p->m_upfilename, "r" );

//             if( !pf )    

//             {

//                 fprintf( stderr, "cannot open file: %s \n", p->m_upfilename ); 

//                 return 0;

//             }

//         }

// 

//         if( pf )

//         {

//             int nread = fread( ptr, size, nmemb, pf );

//             if( !nread )

//             {

//                 fclose( pf );

//                 pf = NULL;    

//             }

//             

//             return nread;

//         }

// 

//         return 0;

//     }



}; //end namespace

测试程序:

 

#include "HCUrl.h"

#include <string.h>

using namespace OSLib;

class MyCCUrl : public CCUrl
{
protected:
    int process( void* data, size_t size, size_t nmemb )
    {
        //printf( "\n================entering size=%d================\n", size * nmemb );

        printf( "%s", (char*)data );
        return size * nmemb;
    }    
};


void testCCUrlDoHttpPost( const char* username, const char* password );
void testCCUrlDoHttpGet( const char* name, const char* age );
void testGlobalCleanup( const char* username, const char* password );
void testCCUrlUploadFile( const char* filename );

int main( int argc, char* argv[] )
{
//     if( argc < 3 )        

//     {

//         printf( "usage:%s username password\n", argv[0] );

//         return 0;

//     }

//     testCCUrlDoHttpPost( argv[1], argv[2] );



    if( argc < 3 )        
    {
        printf( "usage:%s name age\n", argv[0] );
        return 0;
    }
    testCCUrlDoHttpGet( argv[1], argv[2] );

//     if( argc < 3 )        

//     {

//         printf( "usage:%s username password\n", argv[0] );

//         return 0;

//     }

//     testGlobalCleanup( argv[1], argv[2] );

    
//     if( argc < 2 )        

//     {

//         printf( "usage:%s filename\n", argv[0] );

//         return 0;

//     }

//     testCCUrlUploadFile( argv[1] );

    
    return 0;
}


void testCCUrlDoHttpPost( const char* username, const char* password )
{
    MyCCUrl cu;
    cu.init();
    char data[1024];
    sprintf( data, "id=%s&passwd=%s", username, password );
    char buf[1024 * 1024];
    char* url = "http://forum.byr.edu.cn/wForum/logon.php";
    cu.doHttpPost( url, data, 10 );
} 

void testCCUrlDoHttpGet( const char* name, const char* age )
{
    MyCCUrl cu;
    cu.init();
    char data[1024];
    sprintf( data, "name=%s&age=%s", name, age );
    char buf[1024 * 1024];
    char url[1024];
    sprintf( url, "http://192.168.3.200:8080/action.get.php", name, age );
    cu.doHttpGet( url, data, 10, 1 );
} 

// void testCCUrlUploadFile( const char* filename )

// {

//     CCUrl cu;

//     cu.init();

//     char url[1024];

//     sprintf( url, "http://192.168.3.200:8080/%s", filename );

//     cu.uploadFile( url, filename );

// } 



void testGlobalCleanup( const char* username, const char* password )
{
    for ( int i = 0; i < 10; i ++ )
    {
        MyCCUrl* cu = new MyCCUrl;
        cu->init();
        char data[1024];
        sprintf( data, "id=%s&passwd=%s", username, password );
        char* url = "http://forum.byr.edu.cn/wForum/logon.php";
        cu->doHttpPost( url, data, 10 );
    
        printf( "\n\n\n=============================================\n\n\n" );
    
        MyCCUrl* cu2 = new MyCCUrl;
        
        cu2->init();
        sprintf( data, "name=%s&age=%s", username, password );
        url = "http://192.168.3.200:8080/action.get.php";
        
        delete cu;    //check after deleting cu, whether cu2 is ok 


        cu2->doHttpGet( url, data, 10 );
        
        delete cu2;
    }

    for ( int i = 0; i < 10; i ++ )
    {
        MyCCUrl* cu = new MyCCUrl;
        cu->init();
        char data[1024];
        char* url = 0;
        
    
        printf( "\n\n\n=============================================\n\n\n" );
    
        MyCCUrl* cu2 = new MyCCUrl;
        
        cu2->init();
        sprintf( data, "name=%s&age=%s", username, password );
        url = "http://192.168.3.200:8080/action.get.php";
        cu2->doHttpGet( url, data, 10 );
        delete cu2;
        
        url = "http://forum.byr.edu.cn/wForum/logon.php";
        sprintf( data, "id=%s&passwd=%s", username, password );
        cu->doHttpPost( url, data, 10 );
        delete cu;    //check after deleting cu, whether cu2 is ok 

    }
}

测试中用到了一个php脚本,用于web服务器端解析:

<html>
     <head>
      <title>PHP action</title>
     </head>
     <body>
        your name is: <?php echo htmlspecialchars($_GET['name']); ?> </br>
        your age is: <?php echo (int)$_GET['age']; ?>
</body>
</html>

可以把main函数中的测试get的方法注释掉,把测试post的部分代码打开,就可以测试post了。post的测试例子用到的url是一个论坛的登录url。直接用就可以了。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孕早期吃了田螺怎么办 误吃田螺的尾巴怎么办 螺母滑丝怎么办取下来 轮胎螺丝滑丝了怎么办 固定孔螺丝滑丝怎么办 小螺丝拧不出来怎么办 小螺丝拧不下来怎么办 螺丝拧的太紧怎么办 大螺母拧不下来怎么办 大螺帽拧不出来怎么办 十字螺丝滑丝了怎么办 六角螺母拧圆了怎么办 饺子冻在盘子上怎么办 煮熟的饺子坨了怎么办 六角螺丝拧圆了怎么办 长杆螺丝滑丝了怎么办 起泡器不起泡了怎么办 不喂母乳涨奶怎么办 螺丝和螺母跟转怎么办 六棱螺丝滑丝了怎么办 苹果6螺丝滑牙了怎么办 外六角螺丝圆了怎么办 小螺丝拧花了怎么办 老人退伍证丢了怎么办 狗狗又拉又吐怎么办 孕妇吃了马兰头怎么办 怀孕吃了马兰头怎么办 吃了茭白和豆腐怎么办 电气焊加工怎么办环评 手上皮肤干燥起皮怎么办 脸上起皮怎么办还痒痒 店铺4周被释放了怎么办 炫舞账号忘了怎么办 椎基底供血不足怎么办? 脑动脉供血不足怎么办 颈椎引起的脑供血不足怎么办 军人保障卡怎么办假的 正常形态精子率低怎么办 前向运动精子21怎么办 前向运动精子22%怎么办 前向运动精子19%怎么办