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