Acceptor-Connector模式一(Acceptor的工作)V2.0

来源:互联网 发布:加拿大研究生留学 知乎 编辑:程序博客网 时间:2024/05/21 06:34

 前言:ACE Acceptor-Connector模式

首先这种模式肯定是面向连接的TCP/IP协议。
不管是什么场景,几乎面向连接的通信程序总是由一端主动发起连接,一端监听等待对方的连接。
这就是接收器-连接器模式(服务器-客户端)。

模式思想

(1)此模式只负责连接的建立,不管有多少连接上来,这个模式都能应对。
(2)至于连接建立之后如何通信,那是通信处理器的事情,与此模式不再有任何关系。
(3)资源的管理总是通过调用函数的返回值来做约定的处理。不用类型如果有特殊的资源管理需求,均可以覆盖父类的方法。

相关类

(1)ACE_Svc_Handler  : ACE_Task (服务处理器)连接服务的本地端,成员变量PEER_STREAM peer_由模板参数化,一般为ACE_SOCK_Stream,负责通信的具体执行。ACE_SOCK_Stream既可以读也可以写socket。
(2)ACE_Acceptor (接受器)该工厂被动的接受连接,并随即初始化一个ACE_Svc_Handler 对象来响应。接收器的handle_input方法截获连接信息,并创建服务处理类,最后执行服务处理类的open方法启动服务处理流程。
(3)ACE_Connector (连接器)该工厂主动的连接到对端接受器,并随即初始化一个ACE_Svc_Handler 对象来响应
(4)ACE_Reactor执行不依赖于应用的一般的消息分发策略

一、接收器的工作

接收器的工作流程:
(1)接收器的open函数会在指定端口监听
(2)将自己与AACE_Event_Handler::ACCEPT_MASK事件一起注册到反应器
(3)对端发起连接请求之后,反应器回调ACE_Acceptor ::handle_input方法
(4)handle_input方法就会创建连接处理器对象,并调用连接处理器的open方法
(5)handle_input方法返回-1的时候反应器就会回调接收器的handle_close方法,(参考ACE_Reactor的工作逻辑)
(6)接收器的handle_close方法主要工作是关闭注册事件,并关闭socket资源(执行peer_acceptor_.close())

二、接收器handle_input的工作

handle_input的工作主要包括三部分:
(1)根据模板参数创建服务处理对象new ACE_Svc_Handler
(2)调用成员ACE_SOCK_Acceptor peer_acceptor_的acceptor方法,指定当连接成功建立之后由服务处理对象ACE_Svc_Handler来处理连接
(3)调用服务处理对象的open方法
1)服务处理对象的open方法会注册ACE_Event_Handler::READ_MASK事件到ACE_Reactor
2)服务处理对象的open方法会发起receive动作开始读,
3)服务处理对象的读取完成会执行handle_input,至于服务处理对象的handle_input方法返回-1则是ACE_Reactor的处理逻辑了。
(4)服务处理对象的open方法如果返回-1,则调用服务处理对象的close方法(),ACE_Svc_Handler的close方法会调用handle_close,进而调用destroy,进而调用delete this
template <typename PEER_STREAM, typename SYNCH_TRAITS> intACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_close (ACE_HANDLE,                                                       ACE_Reactor_Mask){  ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::handle_close");  if (this->reference_counting_policy ().value () ==      ACE_Event_Handler::Reference_Counting_Policy::DISABLED)    {      this->destroy ();    }  return 0;}
template <typename PEER_STREAM, typename SYNCH_TRAITS> voidACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::destroy (void){  ACE_TRACE ("ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::destroy");  // Only delete ourselves if we're not owned by a module and have  // been allocated dynamically.  if (this->mod_ == 0 && this->dynamic_ && this->closing_ == false)    // Will call the destructor, which automatically calls <shutdown>.    // Note that if we are *not* allocated dynamically then the    // destructor will call <shutdown> automatically when it gets run    // during cleanup.    delete this;}

示例

下面的程序会在1500端口持续监听,每当有对端发来连接,就创建本地连接处理对象,创建完之后就通过连接处理对象的open返回-1来告诉反应器来释放该对象。

Acceptor 服务端

#include <ace/Log_Msg.h>#include "ace/Svc_Handler.h"#include <ace/Acceptor.h>#include "ace/SOCK_Acceptor.h"#include "ace/INET_Addr.h"#include "ace/Reactor.h"class My_Time_Server_Handler : public ACE_Svc_Handler<ACE_SOCK_Stream,ACE_NULL_SYNCH>{public:~My_Time_Server_Handler();//由接收器在接收到对端的连接请求之后调用此方法virtual int open(void *){ACE_DEBUG((LM_DEBUG,"one client connection established.\n"));return -1;// ERROR}};My_Time_Server_Handler::~My_Time_Server_Handler(){ACE_DEBUG((LM_DEBUG,"~My_Time_Server_Handler()\n"));}int main(int argc, char *argv[]){ACE_INET_Addr local_addr(1500);ACE_Acceptor<My_Time_Server_Handler,ACE_SOCK_Acceptor> acceptor;acceptor.open(local_addr,ACE_Reactor::instance());//截过连接信息ACE_Reactor::instance()->run_reactor_event_loop();return 0;}
Connector客户端

#include <ace/Log_Msg.h>#include <ace/SOCK_Connector.h>#include "ace/INET_Addr.h"int main(int argc, char *argv[]){ACE_INET_Addr addr(1500,"127.0.0.1"); //remote addressACE_SOCK_Connector client_connetor; // connetor for socket clientACE_SOCK_Stream sock_stream; // stream is for socket read/writeif(client_connetor.connect(sock_stream,addr)==-1) //connect to remote address{ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) %p\n"),ACE_TEXT ("connection failed!")));return -1;}if (sock_stream.close () == -1) //close the connection{ACE_ERROR ((LM_ERROR,ACE_TEXT ("(%P|%t) %p\n"),ACE_TEXT ("sock close")));return -1;}return 0;}

运行结果:每次执行客户端都会创建一个服务端的服务处理对象,并随即被释放(我们故意让open方法返回-1来释放服务处理对象,从而来说明整个事件的流程)





0 0