首页 > 其他 > 详细

实现一个可限制最大连接数的Proactor服务器

时间:2014-04-08 18:10:31      阅读:503      评论:0      收藏:0      [点我收藏+]

在服务器程序实现中,一般要求能够限制服务器的最大连接数,这主要是从服务器的性能方面考虑,当过多的连接到来时,服务器虽然能够处理,但效率非常低下,也就会出现卡机的现象。

在用Proactor框架实现的服务器中可以很容易地做到这一点。ACE_Asynch_Acceptor类有一个虚方法:make_handler(),默认情况下是new一个服务处理对象出来,我们可以让他在适当的时候返回一个空值,这样,新的连接便被拒绝了。

另外为了避免每次都完全构造一个全新的服务处理对象,这里还可以使用预分配的方法,一开始便创建出所有的service对象,当有连接到来时,直接取一个未使用的分配给该连接,当连接关闭时,同时也不delete该对象,而是加到空闲队列中,等下一次有新连接到来时再使用。

实现的代码如下:

#include <ace/Os_main.h>  
#include <ace/Asynch_Acceptor.h>  
#include <ace/Proactor.h>  
#include <list>  

#define LISTEN_PORT 5222              // 服务器监听端口  
#define MAX_CONNS 2                     // 最大连接数  

class HA_Acceptor;  
//连接处理器
class HA_Handler : public ACE_Service_Handler  
{  
public:  
	virtual ~HA_Handler ();  

	void init( HA_Acceptor * acceptor );  

	virtual void open (ACE_HANDLE h, ACE_Message_Block&);  
	virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result);  
	virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &result);  

private:  
	ACE_Asynch_Read_Stream reader_;  
	ACE_Asynch_Write_Stream writer_;  

	HA_Acceptor * acceptor_;  
};  

//连接处理器析构时释放连接
HA_Handler::~HA_Handler ()  
{  
	if (this->handle () != ACE_INVALID_HANDLE)  
		ACE_OS::closesocket (this->handle ());  
}  
//连接处理器初始化时引用其管理者
void HA_Handler::init( HA_Acceptor * acceptor )  
{  
	this->acceptor_ = acceptor;  
}  
//
void HA_Handler::open (ACE_HANDLE h, ACE_Message_Block&)  
{  
	this->handle (h);  
	if (this->reader_.open (*this) != 0 || this->writer_.open (*this) != 0   )  
	{  
		ACE_OS::closesocket (this->handle ());  
		this->acceptor_->free_handler( this );  
		return;  
	}  

	ACE_Message_Block *mb;  
	ACE_NEW_NORETURN (mb, ACE_Message_Block (1024));  
	if (this->reader_.read (*mb, mb->space ()) != 0)  
	{  
		mb->release ();  
		ACE_OS::closesocket (this->handle ());  
		//读取失败时收回连接处理器
		this->acceptor_->free_handler( this );  
	}  
}  

void HA_Handler::handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)  
{  
	ACE_Message_Block &mb = result.message_block ();  
	if (!result.success () || result.bytes_transferred () == 0)  
	{  
		mb.release ();  
		ACE_OS::closesocket (this->handle ());  
		//读取失败时收回连接处理器
		this->acceptor_->free_handler( this );  
	}  
	else  
	{  
		ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Received Data : %c/n"), *mb.rd_ptr()));  
		mb.release();  

		ACE_Message_Block *new_mb;  
		ACE_NEW_NORETURN (new_mb, ACE_Message_Block (1024));  
		this->reader_.read (*new_mb, new_mb->space ());  
	}  
}  

void HA_Handler::handle_write_stream (const ACE_Asynch_Write_Stream::Result &result)  
{  
	result.message_block ().release ();  
}  

class HA_Acceptor : public ACE_Asynch_Acceptor<HA_Handler>  
{  
public:  
	HA_Acceptor();  

	void free_handler( HA_Handler * service );  

private:  
	virtual HA_Handler *make_handler (void);  
	void init_handlers();  

private:  
	typedef std::list<HA_Handler *> T_Handler_List;  
	T_Handler_List handler_list_;  
};  



//连接器
HA_Acceptor::HA_Acceptor() : ACE_Asynch_Acceptor<HA_Handler>()  
{  
	//构造一定数量的连接处理器
	init_handlers();  
}  

void HA_Acceptor::free_handler( HA_Handler * service )  
{  
	//读取失败时收回连接处理器
	this->handler_list_.push_back( service );  
}  

HA_Handler * HA_Acceptor::make_handler (void)  
{  
	//返回一个可用的连接处理器
	if( this->handler_list_.empty() )  
		return 0;  

	HA_Handler * service = this->handler_list_.front();  
	this->handler_list_.pop_front();  

	return service;  
}  

void HA_Acceptor::init_handlers()  
{  

	for( int i = 0; i < MAX_CONNS; ++i )  
	{  
		HA_Handler * service;  
		ACE_NEW( service, HA_Handler );  
		service->init( this );  
		this->handler_list_.push_back( service );  
	}  
}  


int ACE_TMAIN (int, ACE_TCHAR *[])  
{  
	ACE_INET_Addr listen_addr( LISTEN_PORT );  
	HA_Acceptor aio_acceptor;  
	if (0 != aio_acceptor.open (listen_addr, 0, 0, 5, 1, 0, 0))  
		ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p/n"), ACE_TEXT ("acceptor open")), 1);  

	ACE_Proactor::instance ()->proactor_run_event_loop ();  

	return 0;  
} 


参考:http://blog.csdn.net/lfhfut/article/details/943532

实现一个可限制最大连接数的Proactor服务器,布布扣,bubuko.com

实现一个可限制最大连接数的Proactor服务器

原文:http://blog.csdn.net/calmreason/article/details/23161859

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!