c++中使用LibCurl解析http请求数据

     libcurl.lib(或libcurl.so,unix下面尽量实时编译,并且要注意系统版本(32  or 64))是跨平台解析http请求数据的动态库,使用起来非常方便。

     以在Windows下使用为例。

     在使用前,要将libcurl库相关的头文件添加至附加包含目录。

     引用相关库:

              #pragma comment(lib,"ws2_32.lib")  #pragma comment(lib,"winmm.lib") #pragma comment(lib,"wldap32.lib") #pragma comment(lib,"libcurl.lib")

     在预处理器定义中添加:BUILDING_LIBCURL;HTTP_ONLY

      下面就是直接使用libcurl.lib的示例了。

      HttpHelper.h

     

#ifndef HTTPHELPER
#define HTTPHELPER
#include "curl.h"
#include "easy.h"
#include "curlbuild.h"
#include "curlrules.h"
using namespace std;
#include <vector>

//http数据类
class TileInfo
{
public:
	TileInfo()
	{
		data=NULL;
	}
	~TileInfo()
	{
		if (data)
		{
			delete[] data;
			data=NULL;
		}
	}
	char* data;
	long dataSize;
};

//http服务类
class HttpHelper
{
public:
	static HttpHelper* GetInstance();
private:
	HttpHelper(void);
	~HttpHelper(void); 
	//释放单例模式
	class CGarbo
	{
	public:
		~CGarbo()
		{
			if (HttpHelper::m_pInstance)
			{
				//释放资源
				curl_global_cleanup();
				delete HttpHelper::m_pInstance;
				HttpHelper::m_pInstance=NULL;
			}
		}
	};
public:
	//通过http地址获取返回的数据
	bool GetDataByURL(const char* URL,char*& data,int& dataSize);
private:
	bool curlInitTile(CURL *&curl,const char* url,vector<TileInfo*>& vecTileData);
	bool getTileDataByCurl(const char* URL,vector<TileInfo*>& vecTileData);
private:
	static HttpHelper* m_pInstance;
	static std::_Mutex m_muTex;   //线程锁
	static CGarbo m_cGarBo;
};
#endif


      HttpHelper.cpp

     

#include "HttpHelper.h"

HttpHelper* HttpHelper::m_pInstance=NULL;
HttpHelper::CGarbo HttpHelper::m_cGarBo;
std::_Mutex HttpHelper::m_muTex;
HttpHelper::HttpHelper(void)
{

}


HttpHelper::~HttpHelper(void)
{
}

//线程安全的单例模式
HttpHelper* HttpHelper::GetInstance()
{
	if (m_pInstance==NULL)
	{
		m_muTex._Lock();
		if (m_pInstance==NULL)
		{
			m_pInstance=new HttpHelper;
			//初始化curl
			curl_global_init(CURL_GLOBAL_ALL);
		}
		m_muTex._Unlock();
	}
	return m_pInstance;
}

bool HttpHelper::GetDataByURL(const char* URL,char*& data,int& dataSize)
{
	vector<TileInfo*> vecData;
	bool bSuccess=getTileDataByCurl(URL,vecData);
	if (bSuccess)
	{
		//获取数据大小
		vector<TileInfo*>::iterator pIter = vecData.begin();
		for (;pIter!=vecData.end();pIter++)
		{
			dataSize+=((*pIter)->dataSize);
		}
		//数据合并
		pIter = vecData.begin();
		data = new char[dataSize];
		long nBegin=0;
		for (;pIter!=vecData.end();pIter++)
		{
			memcpy(data+nBegin,(*pIter)->data,(*pIter)->dataSize);
			nBegin+=((*pIter)->dataSize);
		}
	}
	//释放内存
	if (vecData.size()>0)
	{
		vector<TileInfo*>::iterator pIter = vecData.begin();
		for (;pIter!=vecData.end();pIter++)
		{
			delete *pIter;
			(*pIter)=NULL;
		}
		vector<TileInfo*>().swap(vecData);
	}
}

//数据回调函数
long writerTile(void* data,int size,int nmemb,vector<TileInfo*>& vecData)
{
	long sizes=size*nmemb;
	TileInfo* tf=new TileInfo;
	tf->data=new char[sizes+1];
	memcpy(tf->data,(char*)data,sizes);
	tf->data[sizes]=0;
	tf->dataSize=sizes;
	vecData.push_back(tf);
	return sizes;
}

//curl句柄初始化
bool HttpHelper::curlInitTile(CURL *&curl,const char* url,vector<TileInfo*>& vecData)
{
	CURLcode code;
	char* error=NULL;
	curl=curl_easy_init();
	if (curl==NULL)
	{
		return false;
	}
	code=curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,error);
	if (code!=CURLE_OK)
	{
		return false;
	}
    curl_easy_setopt(curl,CURLOPT_VERBOSE,1L);
	code=curl_easy_setopt(curl,CURLOPT_URL,url);
	if (code!=CURLE_OK)
	{
		return false;
	}
	code=curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,writerTile);
	if (code!=CURLE_OK)
	{
		return false;
	}
	code=curl_easy_setopt(curl,CURLOPT_WRITEDATA,&vecData);
	if (code!=CURLE_OK)
	{
		return false;
	}
	return true;
}

//发送http请求获取数据
bool HttpHelper::getTileDataByCurl(const char* URL,vector<TileInfo*>& vecTileData)
{
	//定义一个easy handle句柄
	CURL* curl=NULL;
	CURLcode code;
	//初始化
	if (!curlInitTile(curl,URL,vecTileData))
	{
		curl_easy_cleanup(curl);
		return false;
	}
	//执行数据请求
	code = curl_easy_perform(curl);
	if (code!=CURLE_OK)
	{
		curl_easy_cleanup(curl);
		return false;
	}
	//获取数据
	long retCode=0;
	code=curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&retCode);
	if (code==CURLE_OK && retCode==200)
	{
		double length=0;
		code=curl_easy_getinfo(curl,CURLINFO_CONTENT_LENGTH_DOWNLOAD,&length);
	}
	else
	{
		curl_easy_cleanup(curl);
		return false;
	}
	curl_easy_cleanup(curl);
	return true;
}


    

你可能感兴趣的:(C++,http,线程安全,libcurl)