ACE Proactor 异步操作

// proactor_tcp_server.cpp :
//

#include "stdafx.h"

#include "ace/Message_Queue.h"
#include "ace/Asynch_IO.h"
#include "ace/OS.h"
#include "ace/Proactor.h"
#include "ace/Asynch_Acceptor.h"
#include "ace/Log_Msg.h"
#include "ace/streams.h"

#pragma comment(lib,"ACED.lib")

class Service_Proactor : public ACE_Service_Handler
{
public:
	~Service_Proactor()
	{
		if (this->handle() != ACE_INVALID_HANDLE)
			ACE_OS::closesocket(this->handle());
	}

	virtual void open(ACE_HANDLE h, ACE_Message_Block&)
	{
		this->handle(h);
		if (this->reader_.open(*this) != 0)
		{
			ACE_LOG_MSG->log(LM_INFO, ACE_TEXT("%p\n"), 
				ACE_TEXT("HA_Proactive_Service open"));
			delete this;
			return;
		}

		ACE_Message_Block *mb = new ACE_Message_Block(buffer, 1024);

		if (this->reader_.read(*mb, mb->space()) != 0)
		{
			ACE_LOG_MSG->log(LM_INFO, "Begin read fail\n");
			delete this;
			return;
		}
		return;
	}


	// 异步读完成后会调用此函数
	virtual void 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();
			delete this;
			return;
		}
		mb.copy("");    // 结束标记'\0'
		ACE_LOG_MSG->log(LM_INFO, "rev:\t%s\n", mb.rd_ptr());
		mb.release();

		ACE_Message_Block *nmb = new ACE_Message_Block(buffer, 1024);
		if (this->reader_.read(*nmb, nmb->space()) != 0)
			return;
	}

private:
	ACE_Asynch_Read_Stream reader_;
	char buffer[1024];
};



int main(int argc, char *argv[])
{

	ACE_OS_Object_Manager::instance()->starting_up();
	// 指定log信息到proactor_tcp_server.txt文件
	ACE_OSTREAM_TYPE *output = new std::ofstream("proactor_tcp_server.txt");
	ACE_LOG_MSG->msg_ostream(output, 1);
	ACE_LOG_MSG->set_flags(ACE_Log_Msg::OSTREAM);

	ACE_Asynch_Acceptor<Service_Proactor> acceptor;
	if (acceptor.open(ACE_INET_Addr(3000, "127.0.0.1")) == -1)
		return -1;

	// 执行顺序:打开连接成功后,执行异步读操作,
	// 当接收到数据时,handle_events()返回1,然后ACE框架将调用handle_read_stream
	while (true)
	{
		ACE_UINT16 ret = ACE_Proactor::instance()->handle_events();
		ACE_LOG_MSG->log(LM_INFO, "handle_events return %d \r\n", ret);
	}
		
	return 0;
}




// proactor_tcp_client.cpp 
//

#include "stdafx.h"

#include "ace/Message_Queue.h"
#include "ace/Asynch_IO.h"
#include "ace/OS.h"
#include "ace/Proactor.h"
#include "ace/Asynch_Connector.h"
#include "ace/streams.h"
#include <sstream>

#pragma comment(lib,"ACED.lib")

class Service_Proactor : public ACE_Service_Handler
{
public:
	~Service_Proactor()
	{
		if (this->handle() != ACE_INVALID_HANDLE)
			ACE_OS::closesocket(this->handle());
	}

	virtual void open(ACE_HANDLE h, ACE_Message_Block&)
	{
		this->handle(h);
		if (this->writer_.open(*this) != 0)
		{
			ACE_ERROR((LM_ERROR, ACE_TEXT("%p\n"),
				ACE_TEXT("HA_Proactive_Service open")));
			delete this;
			return;
		}

		for (ACE_INT16 i = 0; i < 10; ++i)
		{
			write_data("1234");
			ACE_LOG_MSG->log(LM_INFO, "write data : 1234\r\n");
			ACE_OS::sleep(2);
		}

		return;
	}

	void write_data(const char * data)
	{
		ACE_Message_Block *mb = new ACE_Message_Block(100);
		mb->copy(data);
		if (this->writer_.write(*mb, mb->length()) != 0)
		{
			ACE_OS::printf("Begin write fail\n");
			delete this;
			return;
		}
	}

	// 异步写完成后会调用此函数
	virtual void handle_write_stream(const ACE_Asynch_Write_Stream::Result &result)
	{
		ACE_LOG_MSG->log(LM_INFO, "handle_write_stream() \r\n");
		
		ACE_Message_Block &mb = result.message_block();
		mb.release();
		
		return;
	}
protected:


private:
	ACE_Asynch_Write_Stream writer_;
};

int main(int argc, char *argv[])
{
	ACE_OS_Object_Manager::instance()->starting_up();
	ACE_OSTREAM_TYPE *output = new std::ofstream("proactor_tcp_client.txt");
	ACE_LOG_MSG->msg_ostream(output, 1);
	ACE_LOG_MSG->set_flags(ACE_Log_Msg::OSTREAM);

	ACE_INET_Addr addr(3000, "127.0.0.1");
	Service_Proactor *client = new Service_Proactor();
	ACE_Asynch_Connector<Service_Proactor> connector;

	connector.open();
	if (connector.connect(addr) == -1)
		return -1;

	while (true)
	{
		ACE_UINT16 ret = ACE_Proactor::instance()->handle_events();
		ACE_LOG_MSG->log(LM_INFO, "handle_events return %d \r\n", ret);
	}

	return 0;
}






异步操作实现框架:




1、

所有具体的异步操作,都继承于抽象的ACE_Asynch_Operation,并主要实现open方法。
都拥有一个相应的具体异步操作实现Impl成员,这些Impl都有共同的抽象叫ACE_Asynch_Operation_Impl。


2、

这些具体的异步操作类都跟ACE_Handler相关联,在异步操作类open时,需要指定相关联的ACE_Handler。
当发生相关操作时,比如
ACE_Asynch_Read_Stream发生异步read、
ACE_Asynch_Write_Stream发生异步write
操作完成时就会调用相关联的handle_read_stream、handle_write_stream。
同理其它异步操作也一样的道理。
这事件机制的实现由Proactor,进行路由和分派。
所以需要对Proactor的handle_events进行一直阻塞调用。
当每次handle_events成功返回一次后,就会发生一次异步完成通知调用操作(即handle_xxx_xxx被调用)。


3、

在具体的异步操作实现中的open时,就将会发生了proactor对相关句柄的注册
例如可能会发生对socket句柄、文件句柄等发生注册绑定。这注册过程已封装在框架里头,不用操心。
当这些句柄上所发生的操作完成时,由proactor的循环事件处理并分发通知调用各个相关的handle_xxx_xxx。
Proactor是单例,为大伙共享的。谁都可用它。
但通常我们只要用它来启动事件循环即可。其它的句柄注册绑定啊、事件的完成通知等,框架已经完成了。
启动事件,在相应的事件处理那里做我们要做的工作即可。
启动事件循环可以直接proactor_run_event_loop,
或者自己写循环,调用handle_events。


int
ACE_WIN32_Proactor::register_handle (ACE_HANDLE handle,
                                     const void *completion_key)
{
  ULONG_PTR comp_key (reinterpret_cast<ULONG_PTR> (completion_key));


  // No locking is needed here as no state changes.
  ACE_HANDLE cp = ::CreateIoCompletionPort (handle,
                                            this->completion_port_,
                                            comp_key,
                                            this->number_of_threads_);
 // ...
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值