TcpServer 使用簡介
- 簡介
1)
Poco 的 TcpServer 是一個多線程的 Tcp 服務器。
服務器使用 ServerSocket(Poco 的一個用於初始化服務器的socket的類) 來接收鏈接。ServerSocket 在被傳給 TcpServer 之前必須是處於監聽狀態。
2)
TcpServer 爲到來的鏈接維護一個隊列。隊列是多大呢?默認情況下隊列的大小是和線程池的大小一樣。
3)
當然你也可以去設定 TcpServer 的各個參數來適合自己的實際環境。通過 Poco::Net::TCPServerParams ;
TcpServerParam 類 可以設定最大隊列,最大線程數,設定線程空閒時間,設定 TcpServer 的線程優先級(通常高點比較好)。需要注意的是 TcpServerParam 類只能通過指針使用因爲它的析構是 protocted。
4)
不定數量的線程從隊列獲取鏈接,並去處理鏈接。工作的線程數是自動調整的。依賴於在隊列裏等待的鏈接的個數。
通過限制在隊列裏的 connection 數量,是可以防止服務器被大量的數據淹沒。到來的的 connection 超過隊列的限制,會被立即關閉。 - 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( );
}