Reproduced in: http://www.cnblogs.com/TianFang/archive/2006/12/18/595938.html
Using the reactor framework on the server side
The server-side structure using the reactor framework is as follows:
The server-side registers two event handlers, Clientacceptor and ClientService, and the ClientService class is responsible for communicating with the client, and each ClientService object corresponds to a client socket connection. The clientacceptor is specifically responsible for passively accepting client connections and creating ClientService objects. In this way, there will be 1 Clientacceptor objects and N clientservice objects in a server program with n sockets attached.
The entire server-side process is as follows:
- First, create a Clientacceptor object that registers the Accept_mask event on reactor, and reactor will automatically establish a socket listener on the listening port.
- If there is a socket connection to the port, reactor will automatically callback the Handle_input method, Clientacceptor overloads this method, and creates a ClientService object to handle communication with the client.
- The ClientService object is implemented according to the specific functions of the server, and its processing process is similar to the client program, registering the corresponding callback event and distributing it.
The code is as follows:
1#include <ace/OS.h>2#include <ace/Reactor.h>3#include <ace/SOCK_Connector.h>4#include <ace/SOCK_Acceptor.h>5#include <ace/Auto_Ptr.h>6 7 classClientService: PublicAce_event_handler8 {9 Public:TenAce_sock_stream &peer (void) {return This-Sock_;} One A intOpen (void) - { - //Register read-Ready callback function the return This->reactor ()->register_handler ( This, ace_event_handler::read_mask); - } - - VirtualAce_handle Get_handle (void)Const{return This-sock_.get_handle ();} + - Virtual inthandle_input (ace_handle FD) + { A //a simple echoserver that returns the information of the client at intRev = Peer (). recv (BUF, -); - if(rev<=0) - return-1; - - peer (). Send (Buf,rev); - return 0; in } - to //releasing the appropriate resources + Virtual inthandle_close (Ace_handle, Ace_reactor_mask Mask) - { the if(Mask = =ace_event_handler::write_mask) * return 0; $Mask = Ace_event_handler::all_events_mask |Panax Notoginseng Ace_event_handler::D ont_call; - This->reactor ()->remove_handler ( This, mask); the This-sock_.close (); + Delete This;//when a socket error occurs, the client is automatically deleted and the corresponding resource is freed A return 0; the } + - protected: $ Charbuf[ -]; $ Ace_sock_stream Sock_; - }; - the classClientacceptor: PublicAce_event_handler - {Wuyi Public: the Virtual~clientacceptor () { This->handle_close (Ace_invalid_handle,0);} - Wu intOpen (ConstACE_INET_ADDR &listen_addr) - { About if( This->acceptor_.open (LISTEN_ADDR,1) == -1) $ { -Ace_os::p rintf ("Open Port fail"); - return-1; - } A //Register Accept Connection Callback event + return This->reactor ()->register_handler ( This, ace_event_handler::accept_mask); the } - $ VirtualAce_handle Get_handle (void)Const the{return This-acceptor_.get_handle ();} the the Virtual inthandle_input (ace_handle FD) the { -ClientService *client =NewClientService (); inAuto_ptr<clientservice>p (client); the the if( This->acceptor_.accept (Client->peer ()) = =-1) About { theAce_os::p rintf ("Accept Client Fail"); the return-1; the } + p.release (); -Client->reactor ( This-reactor ()); the if(Client->open () = =-1)BayiClient->handle_close (Ace_invalid_handle,0); the return 0; the } - - Virtual intHandle_close (ace_handle handle, the ace_reactor_mask Close_mask) the { the if( This->acceptor_.get_handle ()! =ace_invalid_handle) the { -Ace_reactor_mask m = Ace_event_handler::accept_mask | the Ace_event_handler::D ont_call; the This->reactor ()->remove_handler ( This, m); the This-acceptor_.close ();94 } the return 0; the } the 98 protected: About ace_sock_acceptor acceptor_; - };101 102 intMainintargcChar*argv[])103 {104Ace_inet_addr Addr ( the,"192.168.1.142"); the clientacceptor server;106 Server.reactor (Ace_reactor::instance ());107 Server.open (addr);108 109 while(true) the {111Ace_reactor::instance ()handle_events (); the }113 the return 0; the}
The code function is relatively simple, you need to pay attention to the following points:
- The way to register events here is not the same as in the previous article, it is more intuitive and convenient to set up and get reactor pointers through the reactor () method of the Ace_event_handler class. The previous article is a pointer to a monomer Reactor obtained by Ace_reactor::instance ().
- When the client socket connection is closed, the corresponding resource needs to be freed and the corresponding code for freeing the resource in the Handle_close method of the ClientService object needs to be noted.
Ace Reactor (Reactor) mode (3)