Poco C++类库使用说明

概要介绍

POCO C++是一个开源的C++类库的集合,它主要提供简单的、快速的网络和可移植应用程序的C++开发,这个类库和C++标准库可以很好的集成并填补C++标准库的功能空缺。POCO库的模块化、高效的设计及实现使得POCO特别适合嵌入式开发

二、模块说明

POCO由4个核心库及若干个附加库组成。核心库是:Foundation、XML、Util和Net。其中的两个附加库是:NetSSL,为Net 库中的网络类提供SSL 支持;Data,用来以统一的形式访问不同的SQL 数据库。POCO致力于进行以网络功能为核心的跨平台C++软件的开发,可以类比于Ruby on Rails对于Web开发的作用——一个功能强大而又简单易用的平台,用来构建妳自己的应用程序。POCO是严格围绕标准ANSI/ISO C++来开发的,并且支持标准库。贡献者们努力地达到以下要素之间的平衡:使用高级的C++特性;保持那些类的可理解性;保持代码的干净、一致及易维护性。
Poco C++类库使用说明_第1张图片

  • 线程
    Poco实现线程的机制,它将线程Thread和线程运行的实体Runnable分离开来,就像一个框架,Thread管理线程优先级,堆栈,维护线程局部变量;而运行的代码是在Runnable的子类run方法中实现的。
#include "Poco/Thread.h" 
#include "Poco/Runnable.h" 
#include  
class HelloRunnable: public Poco::Runnable 
{ 
virtual void run() 
{ 
std::cout << "Hello, bingzhe!" << std::endl; 
} 
}; 

int main(int argc, char** argv) 
{ 
    HelloRunnable runnable; 
    Poco::Thread thread; 
    thread.start(runnable); 
    thread.join(); 
    return 0; 
}

  • 线程池
    线程池初始化可以设置最少线程数和最多线程数。每次start使用一个线程,超出最大线程数后会有异常。
#include "Poco/ThreadPool.h"
#include "Poco/Runnable.h"
#include 
class HelloRunnable: public Poco::Runnable
{
    virtual void run()
    {
        std::cout << "Hello, bingzhe" << std::endl;
    }
};

int main(int argc, char** argv)
{
    Poco::ThreadPool pool(3, 6);//最少2个线程,最多6个线程
    HelloRunnable runnable;
    if( pool.available() > 0 )
    {
        pool.start(runnable);
    }
    pool.joinAll();
    return 0;
}

  • 内存池
    内存池内部使用block数组实现,每次获取到一个block,初始化时可以设置block大小。
#include "Poco/MemoryPool.h" 
#include  
#include  
using Poco::MemoryPool; 

int main(int argc, char** argv) 
{ 
    MemoryPool pool(1024); // unlimited number of 1024 byte blocks 
    char* buffer = reinterpret_cast(pool.get()); 
    std::cin.read(buffer, pool.blockSize()); 
    std::streamsize n = std::cin.gcount(); 
    std::string s(buffer, n); 
    pool.release(buffer); 
    std::cout << s << std::endl; 
    return 0; 
} 

  • 日志
    日志模块对日志经过一系列channel过滤,最后写入文件。FormattingChannel对日志进行格式化,Channel对日志进行管理和输出。
    Poco C++类库使用说明_第2张图片1. 控制台日志
#include "Poco/ConsoleChannel.h"
#include "Poco/FormattingChannel.h"
#include "Poco/PatternFormatter.h"
#include "Poco/Logger.h"
#include "Poco/AutoPtr.h"
using Poco::ConsoleChannel;
using Poco::FormattingChannel;
using Poco::PatternFormatter;
using Poco::Logger;
using Poco::AutoPtr;

int main(int argc, char** argv)
{
    AutoPtr pCons(new ConsoleChannel);
    AutoPtr pPF(new PatternFormatter);
    pPF->setProperty("pattern", "%Y-%m-%d %H:%M:%S %s: %t");
    AutoPtr pFC(new FormattingChannel(pPF, pCons));
    Logger::root().setChannel(pFC);
    Logger::get("TestChannel").information("This is a test");
    return 0;
}

  1. 文件日志
    FileChannel属性说明:
    Path:指明日志文件名
    Rotation:指明日志文件控制策略,如按文件大小管理日志文件,超过一定大小后会生成新的文件。
    Archive:指明日志文件命名和压缩策略。
#include "Poco/Logger.h"
#include "Poco/FileChannel.h"
#include "Poco/AutoPtr.h"
using Poco::Logger;
using Poco::FileChannel;
using Poco::AutoPtr;

int main(int argc, char** argv)
{
    AutoPtr pChannel(new FileChannel);
    pChannel->setProperty("path", "sample.log");
    pChannel->setProperty("rotation", "2 K");
    pChannel->setProperty("archive", "timestamp");
    Logger::root().setChannel(pChannel);
    Logger& logger = Logger::get("TestLogger"); // inherits root channel
    for (int i = 0; i < 100; ++i)
    logger.information("Testing FileChannel");
    return 0;
}

  • HTTP
  1. http server
    实现HTTPRequestHandler和HTTPRequestHandlerFactory,创建HttpServer时创建HTTPRequestHandlerFactory对象,在HTTPRequestHandlerFactory中处理请求时创建与请求对应的HTTPRequestHandler处理器。
#include 
#include 
#include 
#include "Poco/Net/DNS.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketStream.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketStream.h"
#include "Poco/StreamCopier.h"
#include 
#include 
#include 
#include 
#include 

using Poco::Net::DNS;
using Poco::Net::IPAddress;
using Poco::Net::HostEntry;

class RootHandler: public Poco::Net::HTTPRequestHandler
{
public:
    void handleRequest(Poco::Net::HTTPServerRequest& request,
    Poco::Net::HTTPServerResponse& response)
    {
        response.setChunkedTransferEncoding(true);
        response.setContentType("text/html");
        std::ostream& ostr = response.send();
        ostr << "HTTP Server powered by POCO C++ Libraries";
        ostr << "";
        ostr << "

hello

"; ostr << ""; } }; class MyRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory{ public: MyRequestHandlerFactory(){}; ~MyRequestHandlerFactory(){}; public: virtual Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) { return new RootHandler; }; }; int main(int argc, char** argv) { Poco::UInt16 port = 1080; Poco::Net::HTTPServerParams * pParams = new Poco::Net::HTTPServerParams; pParams->setMaxQueued(100); pParams->setMaxThreads(16); Poco::Net::ServerSocket svs(port); // set-up a server socket Poco::Net::HTTPServer srv(new MyRequestHandlerFactory(), svs, pParams); // start the HTTPServer srv.start(); //waitForTerminationRequest(); getchar(); // Stop the HTTPServer srv.stop(); return 0; }
  1. HTTP Get
    HTTPClientSession 表示http session,HTTPRequest 表示http请求,HTTPResponse 表示http响应。
#include "Poco/JSON/Parser.h"
#include "Poco/JSON/ParseHandler.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/StreamCopier.h"
#include "Poco/Dynamic/Var.h"
#include "Poco/JSON/Query.h"
#include "Poco/JSON/PrintHandler.h"
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/StreamCopier.h"
#include "Poco/Net/NetException.h"
#include "Poco/Net/HTMLForm.h"
#include "Poco/URI.h"
#include 
using namespace Poco::Dynamic;
using namespace Poco;
using std::string;
using namespace Poco::JSON;
using namespace Poco::Net;
int main()
{
    try {
        std::string strUrl("http://10.0.1.77:8999/blacklist?id=132623198111196400");
        Poco::URI uri(strUrl);
        HTTPClientSession session(uri.getHost(), uri.getPort());
        HTTPRequest request(HTTPRequest::HTTP_GET, uri.getPathAndQuery());
        session.sendRequest(request);
        HTTPResponse response;
        std::istream &is = session.receiveResponse(response);
        const HTTPResponse::HTTPStatus &status = response.getStatus();
        if (HTTPResponse::HTTPStatus::HTTP_OK == status) {
            std::string result;
            StreamCopier::copyToString(is, result);
            std::cout << result << result.size() << std::endl;
        } else {
            std::cout << status << std::endl;
        }
    } catch (Poco::Exception &e) {
        std::cout << e.message() << std::endl;
}

    return 0;
}

  1. HTTP Post
    HTTPClientSession 表示http session,HTTPRequest 表示http请求,HTTPResponse 表示http响应,HTMLForm 表示表单。
#include 
#include 
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/StreamCopier.h"
#include "Poco/Net/NetException.h"
#include "Poco/Net/HTMLForm.h"
#include "Poco/URI.h"

int main()
{
    try{
        URI url("http://test.xheart.cn/xheartdevelop05/user/login/validate");
        HTTPClientSession session(url.getHost(),url.getPort());
        HTTPRequest request(HTTPRequest::HTTP_POST,url.getPath(),HTTPRequest::HTTP_1_1);
        HTMLForm form;
        form.add("userName", "1220002");
        form.add("password", "1234567");
        form.prepareSubmit(request);
        form.write(session.sendRequest(request));
        HTTPResponse res;
        std::istream & is = session.receiveResponse(res);
        StreamCopier::copyStream(is, std::cout);
    }
    catch(NetException & ex){
        std::cout << ex.displayText(); 
    }
}

  • Websocket
  1. Server
    实现HTTPRequestHandler和HTTPRequestHandlerFactory,创建HttpServer时创建HTTPRequestHandlerFactory对象,在HTTPRequestHandlerFactory中处理请求时创建与请求对应的HTTPRequestHandler处理器。
#include "Poco/Net/HTTPServer.h"
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/HTTPServerParams.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/HTTPServerParams.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/WebSocket.h"
#include "Poco/Net/NetException.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Format.h"
#include 

using Poco::Net::ServerSocket;
using Poco::Net::WebSocket;
using Poco::Net::WebSocketException;
using Poco::Net::HTTPRequestHandler;
using Poco::Net::HTTPRequestHandlerFactory;
using Poco::Net::HTTPServer;
using Poco::Net::HTTPServerRequest;
using Poco::Net::HTTPResponse;
using Poco::Net::HTTPServerResponse;
using Poco::Net::HTTPServerParams;
using Poco::Timestamp;
using Poco::ThreadPool;
using Poco::Util::ServerApplication;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;

class PageRequestHandler: public HTTPRequestHandler
    /// Return a HTML document with some JavaScript creating
    /// a WebSocket connection.
{
public:
    void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
    {
        response.setChunkedTransferEncoding(true);
        response.setContentType("text/html");
        std::ostream& ostr = response.send();
        ostr << "";
        ostr << "";
        ostr << "WebSocketServer";
        ostr << "";
        ostr << "";
        ostr << "";
        ostr << " 

WebSocket Server

"; ostr << "

Run WebSocket Script

"; ostr << ""; ostr << ""; } }; class WebSocketRequestHandler: public HTTPRequestHandler /// Handle a WebSocket connection. { public: void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) { Application& app = Application::instance(); try { WebSocket ws(request, response); app.logger().information("WebSocket connection established."); char buffer[1024]; int flags; int n; do { n = ws.receiveFrame(buffer, sizeof(buffer), flags); app.logger().information(Poco::format("Frame received (length=%d, flags=0x%x).", n, unsigned(flags))); ws.sendFrame(buffer, n, flags); } while (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE); app.logger().information("WebSocket connection closed."); } catch (WebSocketException& exc) { app.logger().log(exc); switch (exc.code()) { case WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION: response.set("Sec-WebSocket-Version", WebSocket::WEBSOCKET_VERSION); // fallthrough case WebSocket::WS_ERR_NO_HANDSHAKE: case WebSocket::WS_ERR_HANDSHAKE_NO_VERSION: case WebSocket::WS_ERR_HANDSHAKE_NO_KEY: response.setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST); response.setContentLength(0); response.send(); break; } } } }; class RequestHandlerFactory: public HTTPRequestHandlerFactory { public: HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request) { Application& app = Application::instance(); app.logger().information("Request from " + request.clientAddress().toString() + ": " + request.getMethod() + " " + request.getURI() + " " + request.getVersion()); for (HTTPServerRequest::ConstIterator it = request.begin(); it != request.end(); ++it) { app.logger().information(it->first + ": " + it->second); } if(request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0) return new WebSocketRequestHandler; else return new PageRequestHandler; } }; int main(int argc, char** argv) { Poco::UInt16 port = 1080; Poco::Net::HTTPServerParams * pParams = new Poco::Net::HTTPServerParams; pParams->setMaxQueued(100); pParams->setMaxThreads(16); Poco::Net::ServerSocket svs(port); // set-up a server socket Poco::Net::HTTPServer srv(new RequestHandlerFactory(), svs, pParams); // start the HTTPServer srv.start(); //waitForTerminationRequest(); getchar(); // Stop the HTTPServer srv.stop(); return 0; }
  1. Client
    和Http client类似,增加了一个WebSocket类来处理websocket数据。
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using Poco::Net::HTTPClientSession;
using Poco::Net::HTTPRequest;
using Poco::Net::HTTPResponse;
using Poco::Net::HTTPServerRequest;
using Poco::Net::HTTPServerResponse;
using Poco::Net::WebSocket;
using Poco::Net::WebSocketException;
using Poco::Exception;
using namespace std;

int main() 
{
    char buffer[1024];
    int flags;
    int n;
    std::string payload;
    try {
        HTTPClientSession cs("echo.websocket.org", 80);
        HTTPRequest request(HTTPRequest::HTTP_GET, "/", "HTTP/1.1");
        HTTPResponse response;
        std::string cmd;
        WebSocket * ws = new WebSocket(cs, request, response); // Causes the timeout
        payload = "SGClient: Hello World!";
        cout << "Send: SGClient: Hello World!" << endl;
        ws->sendFrame(payload.data(), payload.size(), WebSocket::FRAME_TEXT);
        n = ws->receiveFrame(buffer, sizeof(buffer), flags);
        buffer[n] = '\0';
        cout << "Received: " << buffer << endl;
        while (cmd != "exit") {
            cmd = "";
            cout << "Please input[exit]:";
            std::cin >> cmd;
            ws->sendFrame(cmd.data(), cmd.size(), WebSocket::FRAME_TEXT);
            n = ws->receiveFrame(buffer, sizeof(buffer), flags);
            buffer[n] = '\0';
            if (n > 0) {
                std::cout << "Receive: " << buffer << std::endl;
            }
    }
    ws->shutdown();
    } catch (Exception ex) {
        cout << ex.displayText() << endl;
        cout << ex.what() << endl;
        return -1;
    }
}

  • 数据库

数据库操作首先要注册相应的Connector,Session类管理数据库和表,Statement类对表记录进行操作。

  1. SQLite
#include "Poco/SharedPtr.h"
#include "Poco/Tuple.h"
#include "Poco/Data/SessionFactory.h"
#include "Poco/Data/Session.h"
#include "Poco/Data/SQLite/Connector.h"
#include 
#include 

using namespace Poco::Data::Keywords;
using Poco::Data::Session;
using Poco::Data::Statement;

int main(int argc, char** argv)
{
    typedef Poco::Tuple Person;
    typedef std::vector People;

    // register SQLite connector
    Poco::Data::SQLite::Connector::registerConnector();

    // create a session
    Session session("SQLite", "sample.db");

    // drop sample table, if it exists
    session << "DROP TABLE IF EXISTS Person", now;
    
    // (re)create table
    session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now;
    
    // insert some rows
    People people;
    people.push_back(Person("Bart Simpson", "Springfield", 12));
    people.push_back(Person("Lisa Simpson", "Springfield", 10));
    
    Statement insert(session);
    insert << "INSERT INTO Person VALUES(:name, :address, :age)",
        use(people), now;
    
    people.clear();

    // a simple query
    Statement select(session);
    select << "SELECT Name, Address, Age FROM Person",
        into(people),
        now;
    
    for (People::const_iterator it = people.begin(); it != people.end(); ++it)
    {
        std::cout << "Name: " << it->get<0>() << 
            ", Address: " << it->get<1>() << 
            ", Age: " << it->get<2>() <
  • JSON
    格式化JSON使用JSON::Object 类,JSON解析使用JSON::Parser类。使用Dynamic::Var类对JSON对象和变量进行类型转换操作。
#include 
#include "Poco/Dynamic/Var.h"
#include "Poco/Dynamic/Pair.h"
#include "Poco/Dynamic/VarIterator.h"
#include "Poco/JSON/Array.h"
#include 
#include 
#include "Poco/JSON/Parser.h"

using Poco::Dynamic::Var;
using Poco::JSON::Parser;
using Poco::Dynamic::Pair;
using Poco::JSON::Array;
using Poco::JSON::Object;

int main(int argc, const char * argv[]) 
{
    using namespace std;
    Poco::JSON::Object scores;
    scores.set("数学", 98);
    scores.set("英语", 99);
    scores.set("语文", 89);
    scores.set("化学", 100);
    scores.set("物理", 98);
    scores.set("生物", 96);
    Poco::JSON::Object student;
    student.set("name", "小南");
    student.set("address", "四川省成都市锦江区锦华路一段7号爱家丽苑1栋1单元305室");
    student.set("class", "四川省成都市第七中学2010级2班");
    student.set("grade", Poco::Dynamic::Var(scores));
    Poco::Dynamic::Var JSON(student);
    cout << JSON.toString() << endl;
    string theJSON = JSON.toString();
    Poco::JSON::Parser parser;
    Poco::Dynamic::Var json = parser.parse(theJSON);
    Poco::JSON::Object theObj = *json.extract();
    Poco::Dynamic::Var theScores = theObj.get("grade");
    Poco::Dynamic::Var name = theObj.get("name");
    Poco::Dynamic::Var address = theObj.get("address");
    Poco::Dynamic::Var theClass = theObj.get("class");
    Poco::JSON::Object grade = *theScores.extract();
    Poco::Dynamic::Var math = grade.get("数学");
    Poco::Dynamic::Var english = grade.get("英语");
    Poco::Dynamic::Var chinese = grade.get("语文");
    Poco::Dynamic::Var wuli = grade.get("物理");
    Poco::Dynamic::Var shengwu = grade.get("生物");
    Poco::Dynamic::Var huaxue = grade.get("化学");
    cout << "\n\n姓名: " << name.toString() << endl
    << "班级: " << theClass.toString() << endl
    << "地址: " << address.toString() << endl
    << "数学: " << math.convert() << endl
    << "语文: " << chinese.convert() << endl
    << "化学: " << huaxue.convert() << endl
    << "物理: " << wuli.convert() << endl
    << "生物: " << shengwu.convert() << endl;
    return 0;
}

  • XML
  1. 格式化XML
#include "Poco/DOM/Document.h"
#include "Poco/DOM/Element.h"
#include "Poco/DOM/Text.h"
#include "Poco/DOM/AutoPtr.h"
#include "Poco/DOM/DOMWriter.h"
#include "Poco/XML/XMLWriter.h"
#include 

using Poco::XML::Document;
using Poco::XML::Element;
using Poco::XML::Text;
using Poco::XML::AutoPtr;
using Poco::XML::DOMWriter;
using Poco::XML::XMLWriter;

int main(int argc, char** argv)
{
    // build a DOM document and write it to standard output.
    AutoPtr pDoc = new Document;
    
    AutoPtr pRoot = pDoc->createElement("root");
    pDoc->appendChild(pRoot);
    AutoPtr pChild1 = pDoc->createElement("child1");
    AutoPtr pText1 = pDoc->createTextNode("text1");
    pChild1->appendChild(pText1);
    pRoot->appendChild(pChild1);
    AutoPtr pChild2 = pDoc->createElement("child2");
    AutoPtr pText2 = pDoc->createTextNode("text2");
    pChild2->appendChild(pText2);
    pRoot->appendChild(pChild2);
    
    DOMWriter writer;
    writer.setNewLine("\n");
    writer.setOptions(XMLWriter::PRETTY_PRINT);
    writer.writeNode(std::cout, pDoc);
    
    return 0;
}

  1. 解析XML
/*
配置文件,名称test.xml


value1
123





*/

#include "Poco/AutoPtr.h"
#include "Poco/Util/XMLConfiguration.h"
#include 

using namespace std;
using Poco::AutoPtr;
using Poco::Util::XMLConfiguration;

int main(int argc, char** argv)
{
    AutoPtr pConfig(new XMLConfiguration("test.xml"));
    std::string prop1 = pConfig->getString("prop1");
    cout << prop1 << endl;
    int prop2 = pConfig->getInt("prop2");
    cout << prop2 << endl;
    std::string prop3 = pConfig->getString("prop3");
    cout << prop3 << endl;
    std::string prop4 = pConfig->getString("prop3.prop4");
    cout << prop4 << endl;
    prop4 = pConfig->getString("prop3.prop4[@attr]");
    cout << prop4 << endl;
    prop4 = pConfig->getString("prop3.prop4[1][@attr]");
    cout << prop4 << endl;
    return 0;
}

你可能感兴趣的:(Poco)