编辑: 无理的喜欢 | 2017-12-17 |
} //Returns a reference to the underlying stream. ACE_SOCK_Stream &
peer_i() { return this->
peer_;
} private: ACE_SOCK_Stream peer_;
char data [12];
};
class My_Accept_Handler: public ACE_Event_Handler { public: //Constructor My_Accept_Handler(ACE_Addr &
addr) { this->
open(addr);
} //Open the peer_acceptor so it starts to listen //for incoming clients. int open(ACE_Addr &
addr) { peer_acceptor.open(addr);
return 0;
} //Overload the handle input method int handle_input(ACE_HANDLE handle) { //Client has requested connection to server. //Create a handler to handle the connection My_Input_Handler *eh= new My_Input_Handler();
//Accept the connection into the Event Handler if (this->
peer_acceptor.accept (eh->
peer (), // stream 0, // remote address 0, // timeout 1) ==-1) //restart if interrupted ACE_DEBUG((LM_ERROR, Error in connection\n ));
ACE_DEBUG((LM_DEBUG, Connection established\n ));
//Register the input event handler for reading ACE_Reactor::instance()->
register_handler(eh,ACE_Event_Handler::READ_MASK);
//Unregister as the acceptor is not expecting new clients return -1;
} //Used by the reactor to determine the underlying handle ACE_HANDLE get_handle(void) const { return this->
peer_acceptor.get_handle();
} private: Acceptor peer_acceptor;
};
int main(int argc, char * argv[]) { //Create an address on which to receive connections ACE_INET_Addr addr(PORT_NO);
//Create the Accept Handler which automatically begins to listen //for client requests for connections My_Accept_Handler *eh=new My_Accept_Handler(addr);
//Register the reactor to call back when incoming client connects ACE_Reactor::instance()->
register_handler(eh, ACE_Event_Handler::ACCEPT_MASK);
//Start the event loop while(1) ACE_Reactor::instance()->
handle_events();
} 上面的例子创建了两个具体事件处理器.第一个具体事件处理器My_Accept_Handler用于接受和建立从客户到来的连接.另一个事件处理器是My_Input_Handler,它用于在连接建立后对连接进行处理.因而,My_Accept_Handler接受连接,并将实际的处理委托给My_Input_Handler. 图6-3 反应堆的事件处理 在上面的例子中,我们首先创建了一个ACE_INET_Addr地址对象,将我们希望在其上接受连接的端口作为参数传给它.其次,实例化一个类型为My_Accept_Handler的对象.随后地址对象通过My_Accept_Handler的构造器传递给它.My_Accept_Handler有一个用于连接建立的底层 具体接受器 (在讲述 IPC 的一章中有与具体接受器相关的内容).My_Accept_Handler的构造器将对新连接的 侦听 委托给该具体接受器的open()方法.在处理器开始侦听连接后,它在反应堆上登记,通知说在接收到新连接请求时,它需要被回调.为完成此操作,我们采用ACE_Event_Handler::ACCEPT_MASK掩码调用register_handler(). 当反应堆被告知要登记处理器时,它执行 双重分派 来确定事件处理器的底层句柄.为完成此操作,它调用get_handler()方法.因为反应堆使用get_handle()方法来确定底层流的句柄,在My_Accept_Handler中必须实现get_handle()方法.在此例中,我们简单地调用具体接受器的get_handle(),它会将适当的句柄返回给反应堆. 一旦在该句柄上接收到新的连接请求,反应堆会自动地回调My_Accept_Handler的handle_input()方法.随后Accept Handler(接受处理器)实例化一个新的Input Handler(输入处理器),并调用具体接受器的accept()方法来实际地建立连接.注意Input Handler底层的流是作为accept()调用的第一个参数传入的.这使得新实例化的Input Handler中的流被设置为在连接建立(由accept()完成)后立即创建的新流.随后Accept Handler将Input Handler登记到反应堆,通知它如果有任何可读的输入就进行回调(使用ACE_Event_Handler::READ_MASK).随后接受处理器返回-1,使自己从反应堆的内部事件分派表中被拆除. 现在,如果有任何输入从客户到达,反应堆将自动回调My_Input_Handler::handle_input().注意在My_Input_Handler的handle_input()方法中,返回给反应堆是0.这指示我们希望保持它的登记;