莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          ACE Reactor的Echo Server

          Posted on 2009-02-03 11:59 dennis 閱讀(1697) 評論(1)  編輯  收藏 所屬分類: unix網絡編程
          相對完整的修改版本

            1 /************************************************************************ 
            2 * @file: echo.cpp                                                    
            3 * @author: dennis
            4 * @revise: dennis <killme2008@gmail.com> http://www.aygfsteel.com/killme2008
            5 *          相對完整的echo server,可以接受多個客戶端連接,并且可以通過鍵入quit正常關閉
            6 
            7 ************************************************************************/
            8 
            9 #ifdef _DEBUG
           10 #pragma comment (lib,"aced.lib")
           11 #else
           12 #pragma comment (lib,"ace.lib")
           13 #endif
           14 
           15 #include "ace/Reactor.h"
           16 #include "ace/SOCK_Acceptor.h"
           17 #include "ace/os.h"
           18 #include "ace/Log_Msg.h"
           19 #include "ace/inet_addr.h"
           20 #include "ace/Thread_Manager.h"
           21 #include<iostream>
           22 #include<string>
           23 
           24 #define PORT_NO 8080
           25 typedef ACE_SOCK_Acceptor Acceptor;
           26 //forward declaration
           27 class Echo_Handler;
           28 
           29 class Echo_Handler:public ACE_Event_Handler
           30 {
           31 public:
           32     //construcor
           33     Echo_Handler()
           34     {
           35     }
           36     virtual ~Echo_Handler()
           37     {
           38     }
           39     //Called back to handle any input received
           40     int handle_input(ACE_HANDLE)
           41     {
           42         //receive the data
           43         ssize_t recvBytes = peer().recv(data,12);
           44         if(recvBytes <= 0)
           45         {
           46             ACE_DEBUG((LM_DEBUG,"%s\n","客戶端斷開連接"));
           47             return -1;
           48         }
           49         data[recvBytes] = 0;
           50 
           51         ACE_DEBUG((LM_DEBUG,"%s\n",data));
           52 
           53 
           54         if(ACE_OS::strcmp(data,"q"== 0)
           55         {
           56             ACE_DEBUG((LM_DEBUG,"%s\n","客戶端退出"));
           57             peer().close();
           58             return -1;
           59         }
           60         peer().send_n(data,recvBytes);
           61         // do something with the input received.
           62         // 
           63         // keep yourself registerd with the reator
           64         return 0;
           65     }
           66 
           67     int handle_close(ACE_HANDLE h,ACE_Reactor_Mask m)
           68     {
           69         delete this;
           70         return  0;
           71     }
           72 
           73     //Used by the reactor to determine the underlying handle
           74     ACE_HANDLE get_handle()  const 
           75     {
           76         return this->peer_.get_handle();
           77     }
           78 
           79     //Returns a reference to the underlying stream.
           80     ACE_SOCK_Stream& peer()
           81     {
           82         return this->peer_;
           83     }
           84 
           85 private:
           86     ACE_SOCK_Stream peer_;
           87     char data [12];
           88 };
           89 
           90 class Echo_Accept_Handler:public ACE_Event_Handler
           91 {
           92 public:
           93     //Constructor
           94     Echo_Accept_Handler(ACE_Addr &addr)
           95     {
           96         this->open(addr);
           97     }
           98     virtual ~Echo_Accept_Handler(){}
           99     //Open the peer_acceptor so it starts to "listen"
          100     //for incoming clients
          101     int open(ACE_Addr &addr)
          102     {
          103         if(peer_acceptor.open(addr)==-1)
          104             ACE_ERROR_RETURN((LM_ERROR,"啟動服務器錯誤\n"),1);
          105         return 0;
          106     }
          107 
          108     //Overload the handle input method
          109     int handle_input(ACE_HANDLE handle)
          110     {
          111         //Client has requested connection to server.
          112         //Create a handler to handle the connection
          113         Echo_Handler *eh;
          114         ACE_NEW_RETURN(eh,Echo_Handler,-1);
          115         ACE_INET_Addr cliaddr;
          116         //Accept the connection "into" the Event Handler
          117         if(this->peer_acceptor.accept(eh->peer(),//stream
          118             &cliaddr,//remote address
          119             0,//timeout
          120             1== -1)//restart if interrupted
          121             ACE_DEBUG((LM_ERROR,"Error in connection \n"));
          122 
          123         ACE_DEBUG((LM_DEBUG,"連接已經建立,來自%s\n",cliaddr.get_host_addr()));
          124 
          125         //Register the input event handler for reading 
          126         ACE_Reactor::instance()->register_handler(eh,ACE_Event_Handler::READ_MASK);
          127         const char* msg = "按q鍵使服務安全退出\r\n";
          128         eh->peer().send_n(msg,strlen(msg)+1);
          129         return 0;
          130     }
          131 
          132     //Used by the reactor to determine the underlying handle
          133     ACE_HANDLE get_handle(voidconst
          134     {
          135         return this->peer_acceptor.get_handle();
          136     }
          137     int handle_close(ACE_HANDLE h,ACE_Reactor_Mask m){
          138         peer_acceptor.close();
          139         delete this;
          140         return 0;
          141     }
          142 
          143 private:
          144     Acceptor peer_acceptor;
          145 };
          146 class Quit_Handler:public ACE_Event_Handler
          147 {
          148 public:
          149     Quit_Handler(ACE_Reactor* r):ACE_Event_Handler(r){}
          150     virtual int handle_exception(ACE_HANDLE)
          151     {
          152         ACE_DEBUG((LM_DEBUG,"停止服務器中\n"));
          153         reactor()->end_reactor_event_loop();
          154         return -1;
          155     }
          156     int handle_close(ACE_HANDLE h,ACE_Reactor_Mask m)
          157     {
          158         delete this;
          159         return 0;
          160     }
          161     virtual ~Quit_Handler(){}
          162 };
          163 static ACE_THR_FUNC_RETURN run_events (void *arg);
          164 static ACE_THR_FUNC_RETURN controller (void *arg);
          165 int ACE_TMAIN(int argc,char *argv[])
          166 {
          167 
          168     ACE_Reactor* reactor=ACE_Reactor::instance();
          169     if(ACE_Thread_Manager::instance()->spawn(run_events,reactor,THR_DETACHED | THR_SCOPE_SYSTEM)==-1)
          170         return 1;
          171     if(ACE_Thread_Manager::instance()->spawn(controller,reactor,THR_DETACHED | THR_SCOPE_SYSTEM)==-1)
          172         return 1;
          173     return ACE_Thread_Manager::instance()->wait();
          174 }
          175 
          176 static ACE_THR_FUNC_RETURN run_events (void *arg)
          177 {
          178     ACE_Reactor* reactor=ACE_static_cast(ACE_Reactor*,arg);
          179     ACE_INET_Addr addr(PORT_NO);
          180 
          181     Echo_Accept_Handler *eh=0;
          182     ACE_NEW_RETURN(eh,Echo_Accept_Handler(addr),1);
          183 
          184     ACE_Reactor::instance()->owner(ACE_OS::thr_self());
          185     reactor->register_handler(eh,ACE_Event_Handler::ACCEPT_MASK);
          186     ACE_Reactor::instance()->run_reactor_event_loop();
          187     return 0;
          188 }
          189 static ACE_THR_FUNC_RETURN controller (void *arg)
          190 {
          191     ACE_Reactor* reactor=ACE_static_cast(ACE_Reactor*,arg);
          192     Quit_Handler *quit_handler=0;
          193     ACE_NEW_RETURN(quit_handler,Quit_Handler(reactor),1);
          194     for(;;)
          195     {
          196         std::string line;
          197         std::getline(std::cin,line,'\n');
          198         if(line=="quit"){
          199             ACE_DEBUG((LM_DEBUG,"請求停止服務器\n"));
          200             reactor->notify(quit_handler);
          201             break;
          202         }
          203     }
          204     return 0;  
          205 }
          206 



          評論

          # re: ACE Reactor的Echo Server[未登錄]  回復  更多評論   

          2009-09-27 11:18 by test
          henhao
          主站蜘蛛池模板: 柞水县| 轮台县| 英山县| 兴安县| 丘北县| 西青区| 乐陵市| 松溪县| 巴中市| 天长市| 洞口县| 定陶县| 峨山| 泰州市| 德安县| 庆云县| 长沙县| 吉木萨尔县| 高唐县| 蒙城县| 资兴市| 朝阳县| 嫩江县| 探索| 泽普县| 宾阳县| 临邑县| 和田市| 天等县| 定陶县| 鲜城| 内乡县| 曲松县| 威海市| 新巴尔虎右旗| 油尖旺区| 永安市| 西华县| 大冶市| 贺州市| 都匀市|