ACE Reactor的Echo Server-阿里云开发者社区

开发者社区> boxti> 正文

ACE Reactor的Echo Server

简介:
+关注继续查看
相对完整的修改版本

  1 /************************************************************************ 
  2 * @file: echo.cpp                                                    
  3 * @author: dennis
  4 * @revise: dennis <killme2008@gmail.com> http://www.blogjava.net/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 }
文章转自庄周梦蝶  ,原文发布时间 2009-02-03

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
怎么设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程
6328 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
3951 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
7576 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
4962 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
10711 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
1997 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
16265 0
+关注
boxti
12535
10037
文章
1327
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载