Poco TcpServer 介紹

TcpServer 使用簡介

  1. 簡介
    1)
    Poco 的 TcpServer 是一個多線程的 Tcp 服務器。
    服務器使用 ServerSocket(Poco 的一個用於初始化服務器的socket的類) 來接收鏈接。ServerSocket 在被傳給 TcpServer 之前必須是處於監聽狀態。
    2)
    TcpServer 爲到來的鏈接維護一個隊列。隊列是多大呢?默認情況下隊列的大小是和線程池的大小一樣。
    3)
    當然你也可以去設定 TcpServer 的各個參數來適合自己的實際環境。通過 Poco::Net::TCPServerParams ;
    TcpServerParam 類 可以設定最大隊列,最大線程數,設定線程空閒時間,設定 TcpServer 的線程優先級(通常高點比較好)。需要注意的是 TcpServerParam 類只能通過指針使用因爲它的析構是 protocted。
    4)
    不定數量的線程從隊列獲取鏈接,並去處理鏈接。工作的線程數是自動調整的。依賴於在隊列裏等待的鏈接的個數。
    通過限制在隊列裏的 connection 數量,是可以防止服務器被大量的數據淹沒。到來的的 connection 超過隊列的限制,會被立即關閉。
  2. TcpServer 的使用
    1)
    創建自己的線程用於接收鏈接請求,並且把建立的 connection 放進隊列。
    2)
    使用 TcpServerConnection 類來響應一個鏈接。用戶必須創建一個 TcpServerConnection 的子類和一個 TcpServerConnectionFavtory 的子類。
    TcpServer 的構造函數裏必須傳入這個 TcpServerConnectionFactory 的子類。
    這裏 TcpServerConnectionFactory 的子類是 CZhiTcpServer
class CZhiTcpServer : public TCPServerConnectionFactory
{
public:
    inline TCPServerConnection* createConnection(const StreamSocket &socket)
    {
        return new CZhiTcpServerConnection( socket );
    }
};

在TcpServer 構造的適合傳入一個 TcpServerConnectionFactory 的子類對象。你也可以傳入 TcpServerParam 對象來指定 TcpServer 對象的其他特性。

int main()
{
    Poco::Net::ServerSocket serverSocket( 8080 );
    Poco::Timespan timeout( 10, 0 );
    serverSocket.setReceiveTimeout( timeout );
    Poco::Net::TCPServerParams::Ptr param = new Poco::Net::TCPServerParams;
    //設定隊列的最大長度。
    param->setMaxQueued( 100 );
    //設定 TcpServer 最大線程的個數。
    param->setMaxThreads( 100 );
    Poco::Net::TCPServer server( new CZhiTcpServer, serverSocket );
    server.start();
    while( 1 )
    {
        sleep( 10 );
    }
    server.stop( );
}

3)
在 TcpServerConnectionFactory 的子類裏必須重載 
virtual TCPServerConnection* createConnection(const StreamSocket& socket) = 0;
在 createConnection() 方法裏 return 一個用戶定義的處理請求的 TcpServerConnection 的子類。

class CZhiTcpServer : public TCPServerConnectionFactory
{
public:
    inline TCPServerConnection* createConnection(const StreamSocket &socket)
    {
        return new CZhiTcpServerConnection( socket );
    }
};

4)
一個 TcpServerConnection 的子類。必須重載 run() 方法用於處理 connection .

class CZhiTcpServerConnection : public TCPServerConnection
{
public:
    CZhiTcpServerConnection( const StreamSocket& s ):
        TCPServerConnection( s )
    {

    }
    void run( void );
};

這裏 run() 函數裏的功能就是接收數據,並且把接收的數據返回回去。關閉鏈接。

/**
 * @brief CZhiTcpServerConnection::run 處理鏈接請求的主函數
 */
void CZhiTcpServerConnection::run( void )
{
    try
    {
        std::cout << "hello world" << std::endl;
        char buf[ 1024 ] = { 0 };

        socket().receiveBytes( buf, 1024 );
        std::stringstream ssbuf( buf );

        std::cout << "recvData: " << ssbuf.str() << std::endl;
        socket().sendBytes( ssbuf.str().data(),ssbuf.str().length() );
    }
    catch( std::exception& e )
    {
        std::cout << e.what() << std::endl;
    }
}

5)
當 run() 返回的時候這個 TcpServerConnection 子類對象將被 delete ,這個 connection 也將被關閉。
6)
每一個被接收的鏈接都會創建一個 TcpServerConnection 的子類。

完整代碼

#include <Poco/Net/ServerSocket.h>
#include <Poco/Net/TCPServer.h>
#include <Poco/Net/TCPServerConnectionFactory.h>
#include <Poco/Net/TCPServerConnection.h>
#include <Poco/Net/StreamSocket.h>
#include <Poco/Timespan.h>


#include <iostream>
#include <sstream>

using Poco::Net::TCPServerConnectionFactory;
using Poco::Net::TCPServerConnection;//構造函數需要 StreamSocket
using Poco::Net::StreamSocket;

class CZhiTcpServerConnection : public TCPServerConnection
{
public:
    CZhiTcpServerConnection( const StreamSocket& s ):
        TCPServerConnection( s )
    {

    }

    void run( void );

};

/**
 * @brief CZhiTcpServerConnection::run 處理鏈接請求的主函數
 */
void CZhiTcpServerConnection::run( void )
{
    try
    {
        std::cout << "hello world" << std::endl;
        char buf[ 1024 ] = { 0 };

        socket().receiveBytes( buf, 1024 );
        std::stringstream ssbuf( buf );

        std::cout << "recvData: " << ssbuf.str() << std::endl;
        socket().sendBytes( ssbuf.str().data(),ssbuf.str().length() );
    }
    catch( std::exception& e )
    {
        std::cout << e.what() << std::endl;
    }
}




class CZhiTcpServer : public TCPServerConnectionFactory
{
public:

    inline TCPServerConnection* createConnection(const StreamSocket &socket)
    {
        return new CZhiTcpServerConnection( socket );
    }

};



int main()
{
    Poco::Net::ServerSocket serverSocket( 8080 );
    Poco::Timespan timeout( 10, 0 );
    serverSocket.setReceiveTimeout( timeout );
    Poco::Net::TCPServerParams::Ptr param = new Poco::Net::TCPServerParams;
    //設定隊列的最大長度。
    param->setMaxQueued( 100 );
    //設定 TcpServer 最大線程的個數。
    param->setMaxThreads( 100 );
    Poco::Net::TCPServer server( new CZhiTcpServer, serverSocket );
    server.start();
    while( 1 )
    {
        sleep( 10 );
    }
    server.stop( );
}

轉載請註明出處 http://blog.csdn.net/yuhaiyang457288/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章