ACE Proactor 异步操作

来源:互联网 发布:淘宝美工可以在家做吗 编辑:程序博客网 时间:2024/05/18 17:26
// 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_streamwhile (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。


intACE_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_); // ...}






0 0