• Windows 10上源码编译Poco并编写httpserver和tcpserver | compile and install poco cpp library on windows


    本文首发于个人博客https://kezunlin.me/post/9587bb47/,欢迎阅读!

    compile and install poco cpp library on windows

    Series

    Guide

    download

    wget https://pocoproject.org/releases/poco-1.8.1/poco-1.8.1.zip
    wget https://pocoproject.org/releases/poco-1.8.1/poco-1.8.1.tar.gz
    

    build

    build options

    buildwin.cmd

        rem Usage:
        rem ------
        rem buildwin VS_VERSION [ACTION] [LINKMODE] [CONFIGURATION] [PLATFORM] [SAMPLES] [TESTS] [TOOL]
        rem VS_VERSION:    90|100|110|120|140|150
        rem ACTION:        build|rebuild|clean
        rem LINKMODE:      static_mt|static_md|shared|all
        rem CONFIGURATION: release|debug|both
        rem PLATFORM:      Win32|x64|WinCE|WEC2013
        rem SAMPLES:       samples|nosamples
        rem TESTS:         tests|notests
        rem TOOL:          devenv|vcexpress|wdexpress|msbuild
    

    we choose to build with visual studio 2015

    build_vs140.cmd

        @echo off
        buildwin 140 build shared release x64 samples
    

    build

    ./build_vs140.cmd
    

    or

    cmake-gui ..
    

    cmake-gui and open sln to build with release x64and install to C:/Program Files/Poco so that find_package(Poco REQURIED) take effect.

    $ ls Poco
    
    bin  include  lib
    
    $ ll Poco/lib
    
    total 3.5M
    drwxr-xr-x 1 zunli zunli     0 Jan 25 07:39 cmake
    -rw-r--r-- 1 zunli zunli  1.5M Jan 25 06:59 PocoFoundation.lib
    -rw-r--r-- 1 zunli zunli  111K Jan 25 06:59 PocoJSON.lib
    -rw-r--r-- 1 zunli zunli 1007K Jan 25 07:00 PocoNet.lib
    -rw-r--r-- 1 zunli zunli  320K Jan 25 07:00 PocoUtil.lib
    -rw-r--r-- 1 zunli zunli  595K Jan 25 07:00 PocoXML.lib
    

    Poco Example

    CMakeLists.txt

    cmake_minimum_required (VERSION 2.6)
    
    project (event_demo)
    enable_language(C)
    enable_language(CXX)
    
    # Always include the source and build directories in the include path.
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    # Set the output folder where your program will be created
    set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
    set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
    set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
    
    find_package(Poco REQUIRED COMPONENTS Foundation Util Net XML JSON)
    
    # no Poco_INCLUDE_DIRS, we have to set by hand 
    if(MSVC) # WIN32
    	SET(Poco_INCLUDE_DIRS "C:/Program Files/Poco/include")
    else()
    	SET(Poco_INCLUDE_DIRS "/usr/local/include/Poco")
    endif(MSVC)
    
    MESSAGE( [Main] " Poco_INCLUDE_DIRS = ${Poco_INCLUDE_DIRS}")
    MESSAGE( [Main] " Poco_LIBRARIES = ${Poco_LIBRARIES}")
    
    # The following folder will be included
    include_directories(
        ${MY_SRC_INCLUDE}  
    	${Poco_INCLUDE_DIRS} 
        )   
    
    link_directories(${CMAKE_BINARY_DIR}) 
    
    add_executable(event_demo event_demo.cpp)
    target_link_libraries(event_demo ${Poco_LIBRARIES})
    

    Notice 1: find_package(Poco REQUIRED COMPONENTS Foundation Util Net XML JSON) and use ${Poco_INCLUDE_DIRS}, ${Poco_LIBRARIES}.

    Notice 2: we have to set SET(Poco_INCLUDE_DIRS "C:/Program Files/Poco/include") by hand.

    event

    event_demo.cpp

    #include "Poco/BasicEvent.h"
    #include "Poco/Delegate.h"
    #include <iostream>
    
    using Poco::BasicEvent;
    using Poco::Delegate;
    
    class Source
    {
    public:
        BasicEvent<int> theEvent;
    
        void fireEvent(int n)
        {
            theEvent(this, n);
        }
    };
    
    class Target
    {
    public:
        void onEvent(const void* pSender, int& arg)
        {
            std::cout << "onEvent: " << arg << std::endl;
        }
    };
    
    int main(int argc, char** argv)
    {
        Source source;
        Target target;
    
        source.theEvent += Delegate<Target, int>(
            &target, &Target::onEvent);
    
        source.fireEvent(42);
    
        source.theEvent -= Delegate<Target, int>(
            &target, &Target::onEvent);
    
        return 0;
    }
    

    active method

    #include "Poco/ActiveMethod.h"
    #include "Poco/ActiveResult.h"
    #include <utility>
    #include <iostream>
    
    using Poco::ActiveMethod;
    using Poco::ActiveResult;
    
    class ActiveAdder
    {
    public:
    	ActiveAdder() : add(this, &ActiveAdder::addImpl)
    	{
    	}
    
    	ActiveMethod<int, std::pair<int, int>, ActiveAdder> add;
    
    private:
    	int addImpl(const std::pair<int, int>& args)
    	{
    		return args.first + args.second;
    	}
    };
    
    int main(int argc, char** argv)
    {
    	ActiveAdder adder;
    
    	ActiveResult<int> sum = adder.add(std::make_pair(1, 2));
    	// do other things
    	sum.wait();
    	std::cout << sum.data() << std::endl;
    
    	return 0;
    }
    

    http server

    #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/Timestamp.h"
    #include "Poco/DateTimeFormatter.h"
    #include "Poco/DateTimeFormat.h"
    #include "Poco/Exception.h"
    #include "Poco/ThreadPool.h"
    #include "Poco/Util/ServerApplication.h"
    #include "Poco/Util/Option.h"
    #include "Poco/Util/OptionSet.h"
    #include "Poco/Util/HelpFormatter.h"
    #include <iostream>
    
    using Poco::Net::ServerSocket;
    using Poco::Net::HTTPRequestHandler;
    using Poco::Net::HTTPRequestHandlerFactory;
    using Poco::Net::HTTPServer;
    using Poco::Net::HTTPServerRequest;
    using Poco::Net::HTTPServerResponse;
    using Poco::Net::HTTPServerParams;
    using Poco::Timestamp;
    using Poco::DateTimeFormatter;
    using Poco::DateTimeFormat;
    using Poco::ThreadPool;
    using Poco::Util::ServerApplication;
    using Poco::Util::Application;
    using Poco::Util::Option;
    using Poco::Util::OptionSet;
    using Poco::Util::OptionCallback;
    using Poco::Util::HelpFormatter;
    
    class TimeRequestHandler : public HTTPRequestHandler
    {
    public:
    	TimeRequestHandler(const std::string& format) : _format(format)
    	{
    	}
    
    	void handleRequest(HTTPServerRequest& request,
    		HTTPServerResponse& response)
    	{
    		Application& app = Application::instance();
    		app.logger().information("[LOG] Request from "
    			+ request.clientAddress().toString());
    
    		Timestamp now;
    		std::string dt(DateTimeFormatter::format(now, _format));
    
    		response.setChunkedTransferEncoding(true);
    		response.setContentType("text/html");
    
    		std::ostream& ostr = response.send();
    		ostr << "<html><head><title>HTTPTimeServer powered by "
    			"POCO C++ Libraries</title>";
    		ostr << "<meta http-equiv="refresh" content="1"></head>";
    		ostr << "<body><p style="text-align: center; "
    			"font-size: 48px;">";
    		ostr << dt;
    		ostr << "</p></body></html>";
    	}
    
    private:
    	std::string _format;
    };
    
    class TimeRequestHandlerFactory : public HTTPRequestHandlerFactory
    {
    public:
    	TimeRequestHandlerFactory(const std::string& format) :
    		_format(format)
    	{
    	}
    
    	HTTPRequestHandler* createRequestHandler(
    		const HTTPServerRequest& request)
    	{
    		if (request.getURI() == "/")
    			return new TimeRequestHandler(_format);
    		else
    			return 0;
    	}
    
    private:
    	std::string _format;
    };
    
    class HTTPTimeServer : public Poco::Util::ServerApplication
    {
    public:
    	HTTPTimeServer() : _helpRequested(false)
    	{
    	}
    
    	~HTTPTimeServer()
    	{
    	}
    
    protected:
    	void initialize(Application& self)
    	{
    		Application& app = Application::instance();
    		app.logger().information("[HTTPTimeServer] initialize port=9980 ");
    
    		loadConfiguration();
    		ServerApplication::initialize(self);
    	}
    
    	void uninitialize()
    	{
    		Application& app = Application::instance();
    		app.logger().information("[HTTPTimeServer] uninitialize ");
    
    		ServerApplication::uninitialize();
    	}
    
    	void defineOptions(OptionSet& options)
    	{
    		ServerApplication::defineOptions(options);
    
    		options.addOption(
    			Option("help", "h", "display argument help information")
    			.required(false)
    			.repeatable(false)
    			.callback(OptionCallback<HTTPTimeServer>(
    				this, &HTTPTimeServer::handleHelp)));
    	}
    
    	void handleHelp(const std::string& name,
    		const std::string& value)
    	{
    		HelpFormatter helpFormatter(options());
    		helpFormatter.setCommand(commandName());
    		helpFormatter.setUsage("OPTIONS");
    		helpFormatter.setHeader(
    			"A web server that serves the current date and time.");
    		helpFormatter.format(std::cout);
    		stopOptionsProcessing();
    		_helpRequested = true;
    	}
    
    	int main(const std::vector<std::string>& args)
    	{
    		Application& app = Application::instance();
    		app.logger().information("[HTTPTimeServer] main ");
    
    		if (!_helpRequested)
    		{
    			unsigned short port = (unsigned short)
    				config().getInt("HTTPTimeServer.port", 9980);
    			std::string format(
    				config().getString("HTTPTimeServer.format",
    					DateTimeFormat::SORTABLE_FORMAT));
    
    			ServerSocket svs(port);
    			HTTPServer srv(new TimeRequestHandlerFactory(format),
    				svs, new HTTPServerParams);
    			srv.start();
    			waitForTerminationRequest();
    			srv.stop();
    		}
    		return Application::EXIT_OK;
    	}
    
    private:
    	bool _helpRequested;
    };
    
    int main(int argc, char** argv)
    {
    	HTTPTimeServer app;
    	return app.run(argc, argv);
    	//visit http://localhost:9980
    }
    

    tcp server/client

    tcpserver

    //
    // TimeServer.cpp
    //
    // This sample demonstrates the TCPServer and ServerSocket classes.
    //
    // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
    // and Contributors.
    //
    // SPDX-License-Identifier:	BSL-1.0
    //
    
    
    #include "Poco/Net/TCPServer.h"
    #include "Poco/Net/TCPServerConnection.h"
    #include "Poco/Net/TCPServerConnectionFactory.h"
    #include "Poco/Net/TCPServerParams.h"
    #include "Poco/Net/StreamSocket.h"
    #include "Poco/Net/ServerSocket.h"
    #include "Poco/Timestamp.h"
    #include "Poco/DateTimeFormatter.h"
    #include "Poco/DateTimeFormat.h"
    #include "Poco/Exception.h"
    #include "Poco/Util/ServerApplication.h"
    #include "Poco/Util/Option.h"
    #include "Poco/Util/OptionSet.h"
    #include "Poco/Util/HelpFormatter.h"
    #include <iostream>
    
    
    using Poco::Net::ServerSocket;
    using Poco::Net::StreamSocket;
    using Poco::Net::TCPServerConnection;
    using Poco::Net::TCPServerConnectionFactory;
    using Poco::Net::TCPServer;
    using Poco::Timestamp;
    using Poco::DateTimeFormatter;
    using Poco::DateTimeFormat;
    using Poco::Util::ServerApplication;
    using Poco::Util::Application;
    using Poco::Util::Option;
    using Poco::Util::OptionSet;
    using Poco::Util::HelpFormatter;
    
    
    class TimeServerConnection : public TCPServerConnection
    	/// This class handles all client connections.
    	///
    	/// A string with the current date and time is sent back to the client.
    {
    public:
    	TimeServerConnection(const StreamSocket& s, const std::string& format) :
    		TCPServerConnection(s),
    		_format(format)
    	{
    	}
    
    	void run()
    	{
    		Application& app = Application::instance();
    		app.logger().information("Request from " + this->socket().peerAddress().toString());
    		try
    		{
    			Timestamp now;
    			//std::string dt(DateTimeFormatter::format(now, _format));
    			//dt.append("
    ");
    			std::string dt("hello world");
    			std::string info("sending:  [" + dt + "] with length="+std::to_string(dt.length()) );
    			app.logger().information(info);
    			socket().sendBytes(dt.data(), (int)dt.length());
    		}
    		catch (Poco::Exception& exc)
    		{
    			app.logger().log(exc);
    		}
    	}
    
    private:
    	std::string _format;
    };
    
    
    class TimeServerConnectionFactory : public TCPServerConnectionFactory
    	/// A factory for TimeServerConnection.
    {
    public:
    	TimeServerConnectionFactory(const std::string& format) :
    		_format(format)
    	{
    	}
    
    	TCPServerConnection* createConnection(const StreamSocket& socket)
    	{
    		return new TimeServerConnection(socket, _format);
    	}
    
    private:
    	std::string _format;
    };
    
    
    class TimeServer : public Poco::Util::ServerApplication
    	/// The main application class.
    	///
    	/// This class handles command-line arguments and
    	/// configuration files.
    	/// Start the TimeServer executable with the help
    	/// option (/help on Windows, --help on Unix) for
    	/// the available command line options.
    	///
    	/// To use the sample configuration file (TimeServer.properties),
    	/// copy the file to the directory where the TimeServer executable
    	/// resides. If you start the debug version of the TimeServer
    	/// (TimeServerd[.exe]), you must also create a copy of the configuration
    	/// file named TimeServerd.properties. In the configuration file, you
    	/// can specify the port on which the server is listening (default
    	/// 9911) and the format of the date/time string sent back to the client.
    	///
    	/// To test the TimeServer you can use any telnet client (telnet localhost 9911).
    {
    public:
    	TimeServer() : _helpRequested(false)
    	{
    	}
    
    	~TimeServer()
    	{
    	}
    
    protected:
    	void initialize(Application& self)
    	{
    		loadConfiguration(); // load default configuration files, if present
    		ServerApplication::initialize(self);
    	}
    
    	void uninitialize()
    	{
    		ServerApplication::uninitialize();
    	}
    
    	void defineOptions(OptionSet& options)
    	{
    		ServerApplication::defineOptions(options);
    
    		options.addOption(
    			Option("help", "h", "display help information on command line arguments")
    			.required(false)
    			.repeatable(false));
    	}
    
    	void handleOption(const std::string& name, const std::string& value)
    	{
    		ServerApplication::handleOption(name, value);
    
    		if (name == "help")
    			_helpRequested = true;
    	}
    
    	void displayHelp()
    	{
    		HelpFormatter helpFormatter(options());
    		helpFormatter.setCommand(commandName());
    		helpFormatter.setUsage("OPTIONS");
    		helpFormatter.setHeader("A server application that serves the current date and time.");
    		helpFormatter.format(std::cout);
    	}
    
    	int main(const std::vector<std::string>& args)
    	{
    		if (_helpRequested)
    		{
    			displayHelp();
    		}
    		else
    		{
    			// get parameters from configuration file
    			unsigned short port = (unsigned short)config().getInt("TimeServer.port", 9911);
    			std::string format(config().getString("TimeServer.format", DateTimeFormat::ISO8601_FORMAT));
    
    			// set-up a server socket
    			ServerSocket svs(port);
    			// set-up a TCPServer instance
    			TCPServer srv(new TimeServerConnectionFactory(format), svs);
    			// start the TCPServer
    			srv.start();
    			// wait for CTRL-C or kill
    			waitForTerminationRequest();
    			// Stop the TCPServer
    			srv.stop();
    		}
    		return Application::EXIT_OK;
    	}
    
    private:
    	bool _helpRequested;
    };
    
    
    int main(int argc, char** argv)
    {
    	TimeServer app; // 9911
    	return app.run(argc, argv);
    }
    

    start tcpserver.

    tcpclient

    //
    // TimeClient.cpp
    //
    
    #include "Poco/Net/SocketAddress.h"
    #include "Poco/Net/StreamSocket.h"
    #include <iostream>
    
    using Poco::Net::SocketAddress;
    using Poco::Net::StreamSocket;
    
    int main(int argc, char** argv)
    {
    	SocketAddress sa("127.0.0.1",9911);
    	StreamSocket ss(sa);
    	int n;
    	char buffer[256];
    	
    	//n = 11 , s[0,1,2,....10] = hello world s[11]=''
    	n = ss.receiveBytes(buffer, sizeof(buffer)-1);
    	buffer[n] = '';
    
    	std::cout << buffer << std::endl;
    	std::cout << n << std::endl;
    }
    

    start tcpclient to receive data from tcpserver.

    telnet as tcpclient

    install telnet on windows by contron panel.

    telnet localhost 9911
    

    Reference

    History

    • 20180125: created.

    Copyright

  • 相关阅读:
    通过调用C语言的库函数与在C代码中使用内联汇编两种方式来使用同一个系统调用来分析系统调用的工作机制
    解密腾讯课堂视频缓存文件
    Pycharm启动后加载anaconda一直updating indices造成Pycharm闪退甚至电脑崩溃
    Pycharm基本设置和插件安装
    Pycharm配置anaconda环境
    Anaconda管理Python环境
    Markdown介绍及工具推荐
    Android应用性能测试
    常用的adb命令
    QTP入门——玩玩小飞机
  • 原文地址:https://www.cnblogs.com/kezunlin/p/11840406.html
Copyright © 2020-2023  润新知