Poco库完全使用手册

什么是POCO库?

POCO库是强大的的跨平台C++库,可以用来编写多平台的网络应用程序,这些平台包括桌面端、服务端、移动端、IOT(物联网)、嵌入式系统等。总的来说是一个非常强大的综合性库。

为什么使用Poco库?

1.支持跨平台

2.性能表现优异

3.API使用方便,便于上手

4.库可以拆分使用,容易实现轻量化调用

5.功能模块丰富

6.Poco C++库是在Boost软件许可证下授权的,既可以用来开发非商业应用,也可以用来开发商业应用。可以说是可以自由使用的了。

POCO库都能做哪些事?

根据Poco官方文档介绍Poco库支持的功能组如下:

1.类型和字节序操作

2.错误处理和调试

3.内存管理

4.字符串和文本的格式化

5.平台和环境的操作和处理

6.随机数生成和各种哈希算法

7.时间和日期处理

8.文件操作系统处理

9.通知和事件

10.各种流处理

11.日志操作

12.动态的库操作

13.进程管理

14.url和uuid的生成和操作

15.XML和Json文件操作

16.网络编程

17.客户端程序和网络程序的编写

18.文件系统的支持和配置

19.日志系统的配置

总的来说就是能用到的功能poco库都支持,可以说是非常强大了。

源码下载和库编译?

Poco库的官网地址

https://pocoproject.org/index.html

Poco库的项目地址

https://github.com/pocoproject/poco/tree/master

Poco库可以根据使用需求不同,编译成静态库或者动态库,编译方法很简单,这里就不再做详细介绍了。

Poco库常用功能:

MD5值计算、Base64加密计算、HMAC-MD5计算

#include 
#include 
#include 

//MD5值的计算
#include "Poco\MD5Engine.h"
#include "Poco\DigestStream.h"
#include "Poco\StreamCopier.h"

using Poco::DigestEngine;
using Poco::MD5Engine;
using Poco::DigestOutputStream;
using Poco::StreamCopier;

//base64的计算
#include "Poco\Base64Decoder.h"
#include "Poco\StreamCopier.h"
#include "Poco\Base64Encoder.h"

using Poco::Base64Encoder;
using Poco::StreamCopier;
using Poco::Base64Decoder;

//计算HMAC-MD5值
#include "Poco/HMACEngine.h"
#include "Poco/MD5Engine.h"
#include "Poco/DigestStream.h"
#include "Poco/StreamCopier.h"
#include 
#include 


using Poco::DigestEngine;
using Poco::HMACEngine;
using Poco::MD5Engine;
using Poco::DigestOutputStream;
using Poco::StreamCopier;

using namespace std;
int main(int argc, char** argv)
{
	//计算文件的MD5值
	ifstream inputStream("test.txt", ios::binary);
	MD5Engine md5;
	DigestOutputStream dos(md5);
	StreamCopier::copyStream(inputStream, dos);
	dos.close();
	cout << DigestEngine::digestToHex(md5.digest()) << std::endl;
	cout << "完成md5值的计算" << endl;

	//计算字符串的MD5值
	std::string INPUT_STRING = "hello";
	stringstream stringStream(INPUT_STRING);
	StreamCopier::copyStream(stringStream, dos);
	dos.close();
	cout << DigestEngine::digestToHex(md5.digest()) << std::endl;
	cout << "字符串md5值计算完毕" << endl;

	//对文件进行base64加密
	ifstream base64EncodeInputStream("test.txt", ios::binary);
	ofstream base64EncodeOutputStream("encoderesult.txt");
	Base64Encoder encoder(base64EncodeOutputStream);
	StreamCopier::copyStream(base64EncodeInputStream, encoder);
	cout << "完成base64加密" << endl;
	encoder.close();
	
	//对文件进行解密
	ofstream base64DecodeOutputStream("decoderesult.txt");
	ifstream base64DecodeInputStream("encoderesult.txt");
	Base64Decoder decoder(base64DecodeInputStream);
	StreamCopier::copyStream(decoder,base64DecodeOutputStream);

	//对字符串进行加密
	stringstream strbase64encodeinputstream(string("ceshibase64"));
	string strbase64encodeoutputStr;
	stringstream strencodeOutputStream;
	
	Base64Encoder stringencodr(strencodeOutputStream);
	StreamCopier::copyStream(strbase64encodeinputstream, stringencodr);
	stringencodr.close();
	strencodeOutputStream >> strbase64encodeoutputStr;

	//对字符串进行解密
	stringstream strdecodeInputstream(strbase64encodeoutputStr);
	stringstream strdecodeOutputstream;
	string decodeResult;
	Base64Decoder stringdecoder(strdecodeInputstream);
	StreamCopier::copyStream(stringdecoder, strdecodeOutputstream);
	strdecodeOutputstream >> decodeResult;

	//计算文件的HMAC-MD5值
	string passphrase("hmac-key");
	ifstream hmacinputStream("test.txt", ios::binary);

	HMACEngine hmac(passphrase);
	DigestOutputStream hmacdos(hmac);
	StreamCopier::copyStream(hmacinputStream, hmacdos);
	hmacdos.close();
	cout << DigestEngine::digestToHex(hmac.digest()) << std::endl;

	//计算字符串的HMAC-MD5值
	stringstream hmacStrinputStream("ceshishiyong");
	HMACEngine hStrmac(passphrase);
	DigestOutputStream hmaStrcdos(hStrmac);
	StreamCopier::copyStream(hmacStrinputStream, hmaStrcdos);
	hmaStrcdos.close();
	cout << DigestEngine::digestToHex(hStrmac.digest()) << std::endl;

}

使用Poco库来搭建服务程序

服务的程序类似于一个线程池程序,每个人物都是是一个子线程运行在对应的线程池当中。线程池的程序类似于下面:

#include "Poco/Util/ServerApplication.h"
#include "Poco/Logger.h"

class MyServer : public Poco::Util::ServerApplication
{
public:
     MyServer();
     virtual ~ MyServer();

    // Poco::Util::ServerApplication overridables
public:
    virtual void initialize(Poco::Util::Application &self) override;
    virtual void uninitialize() override;
    virtual int main(const std::vector& args) override;

private:
	void createLogDir();
};

 

线程池管理器就是所谓的服务器主程序,主程序继承自Poco::Utils::ServerApplication

主要重写三个接口

 

//initialize是初始化接口,在初始化服务器的时候被调用,做些初始化操作
virtual void initialize(Poco::Util::Application &self) override;
//uninitialize是清理操作,在服务器终止的时候被调用,做一些清理的操作
virtual void uninitialize() override;
//main是主函数主要负责对应的主程序
virtual int main(const std::vector& args) override;
#include "MyServer.h"
#include "Poco/TaskManager.h"
#include "Poco/AutoPtr.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/FileChannel.h"
#include "Poco/SplitterChannel.h"
#include "Poco/FormattingChannel.h"
#include "Poco/PatternFormatter.h"
#include "Poco/SimpleFileChannel.h"


#include 
#include 
#include 

void MyServer::initialize(Poco::Util::Application &self)
{
    ServerApplication::initialize(self);
    logger().information("Service is starting up");
}
void MyServer::uninitialize()
{
    logger().information("Service is shutting down");
    ServerApplication::uninitialize();
}

int  MyServer::main(const std::vector& args)
{ 
	HANDLE hMutext = CreateMutexA(NULL, TRUE, " My-service-mutext");
    logger().information("Service is running as %s ...", 
        config().getBool("application.runAsService", false) 
            ? std::string("service") : std::string("command line"));

    Poco::TaskManager taskManager;
	//版本更新
    taskManager.start(new UpdateTask());
    //等待任务取消
    waitForTerminationRequest();
    taskManager.cancelAll();
    //等待取消操作完成
    taskManager.joinAll();

	ReleaseMutex(hMutext);
	hMutext = INVALID_HANDLE_VALUE;
   return Application::EXIT_OK;
}

服务器中的每个人物都是一个线程类似于QT中的QRunnable

Poco中的程序中的每一个人物都继承于Task类,

 

#include "Poco/Task.h"
class MyUpdateTask : public Poco::Task
{
public:
    MyUpdateTask();
    virtual ~ MyUpdateTask();

    // Poco::Task overridables
public:
    //runTask是入口函数
    virtual void runTask() override;
private:
};

主函数中启动服务程序的方法

#include "MyServer.h"
#include 

#ifdef _DEBUG
int main()
{
	HYPYServer server;
	server.main(std::vector());
	return 0;
}
#else
POCO_SERVER_MAIN(HYPYServer)
#endif

使用Poco库进行Https请求访问服务器

https Get 请求

bool UpdateTask::fetchUpdateInfoFromHTTPServer()
{
    //请求的参数
    std::string arg1 = "1";
    std::string arg2 = "2";
    std::string arg3 = "3";

    //拼接对应的请求
	Config config;
    std::string path = "/api/v1/update";
    Poco::URI uri;
    uri.setScheme(config.getServerScheme());
    uri.setHost(config.getServerAddr());
    uri.setPort(config.getServerPort());
    uri.setPath(path);
    uri.addQueryParameter("arg1", arg1);
    uri.addQueryParameter("arg2", arg2);
    uri.addQueryParameter("arg3", arg3);

	Poco::Net::HTTPSClientSession* https_session = OSUtils::CommonUtils::GetHttpsClientSession();
	https_session->setPort(uri.getPort());
	https_session->setHost(uri.getHost());
    std::string pathAndQuery(uri.getPathAndQuery());
    
    Poco::Net::HTTPRequest request(
        Poco::Net::HTTPRequest::HTTP_GET, pathAndQuery,
        Poco::Net::HTTPMessage::HTTP_1_1);
    Poco::Net::HTTPResponse response;
	https_session->sendRequest(request);
    std::istream &streamIn = https_session->receiveResponse(response);

    std::ostringstream responseStream;
    Poco::StreamCopier::copyStream(streamIn, responseStream);

    m_responseContent = responseStream.str();

	delete https_session;
	https_session = nullptr;
    return response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK;
}

HTTP POST下载请求

int MyUpdateTask::UpdateWork(std::string loginid, std::string clientid, std::string& filePath)
{
	try
	{
		Config config;
		std::string path = "/api/v1/dict/download";
		Poco::URI uri;
		uri.setScheme(config.getServerScheme());
		uri.setHost(config.getServerAddr());
		uri.setPort(config.getServerPort());
		uri.setPath(path);

		Poco::Net::HTTPSClientSession* https_session = OSUtils::CommonUtils::GetHttpsClientSession();
		https_session->setHost(uri.getHost());
		https_session->setPort(uri.getPort());

		Poco::Net::HTTPRequest request(
			Poco::Net::HTTPRequest::HTTP_POST, uri.getPathAndQuery(),
			Poco::Net::HTTPMessage::HTTP_1_1);

		Poco::Net::HTMLForm form;
		form.add("loginid", loginid);
		form.add("clientid", clientid);
		form.prepareSubmit(request);

		form.write(https_session->sendRequest(request));

		Poco::Net::HTTPResponse response;
		std::istream &streamIn = https_session->receiveResponse(response);

		
		if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_OK)
		{
			delete https_session;
			https_session = nullptr;
			return 1;
		}

		std::ostringstream responseStream;
		Poco::StreamCopier::copyStream(streamIn, responseStream);
		std::string resultStr = responseStream.str();

		delete https_session;
		https_session = nullptr;

		Poco::JSON::Parser parser;
		auto root = parser.parse(resultStr);
		Poco::JSON::Object::Ptr objRoot = root.extract();
		if (!objRoot)
			return 2;

		int codeResult = objRoot->getValue("code");
		if (codeResult == 200)
		{
			
			dictFilePath = objRoot->getValue("result");
			return 0;
		}
		return codeResult;
	}
	catch (...)
	{
		return 1;
	}
}

https Post MultiPart请求

int MyUpdateTask::UpdateWork(std::string loginid, std::string clientid, std::string path)
{
	try
	{
        //获得对应的请求参数
		Config config;
		std::string path = "/api/v1/dict/ceshi";
		Poco::URI uri;
		uri.setScheme(config.getServerScheme());
		uri.setHost(config.getServerAddr());
		uri.setPort(config.getServerPort());
		uri.setPath(path);

            //获得对应的会话客户端
		Poco::Net::HTTPSClientSession* https_session = OSUtils::CommonUtils::GetHttpsClientSession();
		https_session->setHost(uri.getHost());
		https_session->setPort(uri.getPort());
            
            //生成对应的请求
		Poco::Net::HTTPRequest request(
			Poco::Net::HTTPRequest::HTTP_POST, uri.getPathAndQuery(),
			Poco::Net::HTTPMessage::HTTP_1_1);
		request.setContentType("multipart/form-data");
            
            //在表单中添加对应的参数和文件
		Poco::Net::HTMLForm form;
		form.setEncoding(Poco::Net::HTMLForm::ENCODING_MULTIPART);
		form.add("loginid", loginid);
		form.add("clientid", clientid);
		form.addPart("dict", new Poco::Net::FilePartSource(path));
		form.prepareSubmit(request);
		form.write(https_session->sendRequest(request));
		Poco::Net::HTTPResponse response;
		std::istream &streamIn = https_session->receiveResponse(response);

  		if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_OK)
		{
			delete https_session;
			https_session = nullptr;
			return 1;
		}
			

		std::ostringstream responseStream;
		Poco::StreamCopier::copyStream(streamIn, responseStream);
		std::string resultStr = responseStream.str();

		delete https_session;
		https_session = nullptr;
		
		Poco::JSON::Parser parser;
		auto root = parser.parse(resultStr);
		Poco::JSON::Object::Ptr objRoot = root.extract();
		if (!objRoot)
			return 2;

		int codeResult = objRoot->getValue("code");
		if(codeResult == 200)
		{
			return 0;
		}
		return codeResult;
	}
	catch (...)
	{
		return 1;
	}
}

通过URL下载文件

Poco::URI uri(addrs.at(index).fileUrl);
Poco::Net::HTTPSClientSession* https_session = OSUtils::CommonUtils::GetHttpsClientSession();
https_session->setPort(uri.getPort());
https_session->setHost(uri.getHost());

Poco::Net::HTTPRequest request(
	Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(),
	Poco::Net::HTTPMessage::HTTP_1_1);
Poco::Net::HTTPResponse response;
https_session->sendRequest(request);
std::istream &streamIn = https_session->receiveResponse(response);
if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK)
{
	
 }

使用到的生成https请求的客户端

 

Poco::Net::HTTPSClientSession* OSUtils::CommonUtils::GetHttpsClientSession()
{
	std::string certificate_path = OSUtils::PathUtils::getCertificatePath();
	SSLManager::InvalidCertificateHandlerPtr handlerPtr(new AcceptCertificateHandler(false));
	Context::Ptr context = new Context(Context::TLSV1_2_CLIENT_USE, certificate_path, Poco::Net::Context::VERIFY_NONE, 9);
	SSLManager::instance().initializeClient(nullptr, handlerPtr, context);
	HTTPSClientSession *session = new HTTPSClientSession(context);
	session->setTimeout(5000 * 1000);
	int timeout_sec = session->getTimeout().seconds();
	return session;
}

Poco库解压缩文件

ifstream instream(filepath, ios::binary);
Poco::Zip::Decompress decompress(instream, fileDir);
decompress.decompressAllFiles();
instream.close();
File  zip_file(filepath);
if (zip_file.exists())
	zip_file.remove();

 

 

 

 

你可能感兴趣的:(C/C++,c++,开发语言,经验分享)