[libcurl]_[初级]_[使用libcurl库做简单软件更新解决方案]


场景:

1.软件需要更新版本时,通过读取配置好的xml文件获得软件最新的版本信息。

2.因为访问网络可能造成延迟,所以不能阻碍界面操作,所以还得用工作线程进行操作。

3.使用expat库做xml分析,curl库下载xml数据流,两个都是跨平台的库,使用也比较方便。


libcurl: http://curl.haxx.se/

expat: http://expat.sourceforge.net/

pthread: http://sources.redhat.com/pthreads-win32/


1.要分析的xml文件

http://www.w3school.com.cn/example/xmle/note.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
	<to>George</to>
	<from>John</from>
	<heading>Reminder</heading>
	<body>Don't forget the meeting!</body>
</note> 

2. test_curl.cpp文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <iostream>

#include "curl/curl.h"
#include "expat.h"
#include "pthread.h"
#include "windows.h"

using namespace std;


#define XML_FMT_INT_MOD "l"


static bool bodyStart = false;
static void StartElementHandler(void *userData,const XML_Char *name,
                                const XML_Char **atts)
{
    if(!strcmp("body",name))
    {    
        bodyStart = true;
    }
}

static void EndElementHandler(void *userData,const XML_Char *name)
{
    if(!strcmp("body",name))
    {
        bodyStart = false;
    }
}

static void CharacterDataHandler(void *userData,const XML_Char *s,
                                 int len)
{
    if(bodyStart && s)
    {
        string str(s,len);
        cout << "inner Text: " << str << endl;
    }
}

class DownloadManger
{
    public:
    static DownloadManger* GetInstance()
    {
        if(!download_manger_)
        {
            download_manger_ = new DownloadManger();
        }
        return download_manger_;
    }
    ~DownloadManger()
    {
        download_manger_ = NULL;
        curl_global_cleanup();
    }

    typedef size_t (*WriteMemoryCallback)(void *contents, size_t size, 
        size_t nmemb, void *userp);
    int Process(const char* url,WriteMemoryCallback callback_func,void* userdata)
    {
        CURL *curl_handle = curl_easy_init();

        curl_easy_setopt(curl_handle, CURLOPT_URL, url);
        curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, callback_func);
        curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, userdata);
        curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "test-agent/1.0");

        curl_easy_perform(curl_handle);

        curl_easy_cleanup(curl_handle);
        
        return 0;
    
    }

    private:
    static DownloadManger* download_manger_;
    DownloadManger()
    {
        curl_global_init(CURL_GLOBAL_ALL);
    }
};

DownloadManger* DownloadManger::download_manger_ = NULL;

static size_t DownloadCallback(void *contents, size_t size, 
    size_t nmemb, void *userp)
{
    size_t realsize = size * nmemb;
    XML_Parser parser = (XML_Parser)userp;
  
    if (XML_Parse(parser, (char*) contents, realsize, 0) == XML_STATUS_ERROR)
    {
        fprintf(stderr, "%s at line %" XML_FMT_INT_MOD "u \n",
                XML_ErrorString(XML_GetErrorCode(parser)),
                XML_GetCurrentLineNumber(parser));
        return 0;
    }
    return realsize;
}

XML_Parser CreateExpatParser()
{
    XML_Parser parser = XML_ParserCreate(NULL);
    XML_SetUserData(parser, NULL);
    XML_SetElementHandler(parser, &StartElementHandler,&EndElementHandler);
    {
        XML_SetCharacterDataHandler(parser,&CharacterDataHandler);
    }
    return parser;
}

void FreeExpatParser(XML_Parser parser)
{
    XML_Parse(parser, (char*) 0, 0, 1);
    XML_ParserFree(parser);
}

void * noMutexStartPthread(void * arg)
{
    DWORD id = GetCurrentThreadId();
    cout << "current thread id is: " << id << endl;
    DownloadManger* manager = (DownloadManger*)arg;
    XML_Parser parser = CreateExpatParser();
    manager->Process("http://www.w3school.com.cn/example/xmle/note.xml",
        &DownloadCallback,parser);
    FreeExpatParser(parser);
}

int main(void)
{
    DWORD id = GetCurrentThreadId();
    cout << "main thread id is: " << id << endl;

    DownloadManger* manager = DownloadManger::GetInstance();

    pthread_t t1;
    pthread_create(&t1, NULL, noMutexStartPthread, manager);
    pthread_detach(t1);

    pthread_t t2;
    pthread_create(&t2, NULL, noMutexStartPthread, manager);
    pthread_detach(t2);
    
    int i = 0;
    while(i < 10)
    {
        cout << "." << endl;
        Sleep(1000);
        ++i;
    }

    delete manager;
    return 0;
}




3.Makefile文件:

CP="cp"

test_curl.exe:test_curl.o
	${CP} C:/Users/apple/Desktop/curl/curl-7.28.1/lib/.libs/libcurl-4.dll .
	${CP} E:/software/Lib/file/xml-expat-2.0.1/win32/release/share/libexpat-1.dll .
	${CP} E:/software/Lib/thread/pthreads-w32-2-8-0/win32/release/share/pthreadGC2.dll .
	g++ -o test_curl.exe test_curl.o -L/E/software/Lib/thread/pthreads-w32-2-8-0/win32/release/share -lpthreadGC2 -LC:/Users/apple/Desktop/curl/curl-7.28.1/lib/.libs -lcurl-4 -LE:/software/Lib/file/xml-expat-2.0.1/win32/release/share -lexpat

test_curl.o:test_curl.cpp
	g++ -I/E/software/Lib/thread/pthreads-w32-2-8-0/win32/release/share/include -IE:/software/Lib/file/xml-expat-2.0.1/win32/release/share/include -IC:/Users/apple/Desktop/curl/curl-7.28.1/include -c test_curl.cpp -o test_curl.o


4.运行结果:

main thread id is: 8004
current thread id is: 4856
.
current thread id is: 6988
inner Text: Don't forget the meeting!
.
.
.
inner Text: Don't forget the meeting!
.
.
.
.
.
.




你可能感兴趣的:(C++,xml,libcurl,软件更新,expat)