ACE Reactor的Echo Server

2009 - 02 - 03

ACE Reactor的Echo Server

相对完整的修改版本

1 /* ***********************************************************************
2 *@file:echo.cpp
3 *@author:dennis
4 *@revise:dennis<killme2008@gmail.com> http://www.blogjava.net/killme2008
5 *相对完整的echoserver,可以接受多个客户端连接,并且可以通过键入quit正常关闭
6
7 *********************************************************************** */
8
9 #ifdef_DEBUG
10 #pragmacomment(lib, " aced.lib " )
11 #else
12 #pragmacomment(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 typedefACE_SOCK_AcceptorAcceptor;
26 // forwarddeclaration
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 // Calledbacktohandleanyinputreceived
40 int handle_input(ACE_HANDLE)
41 {
42 // receivethedata
43 ssize_trecvBytes = 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,data));
52
53
54 if (ACE_OS::strcmp(data, " q " ) == 0 )
55 {
56 ACE_DEBUG((LM_DEBUG, " 客户端退出 " ));
57 peer().close();
58 return - 1 ;
59 }
60 peer().send_n(data,recvBytes);
61 // dosomethingwiththeinputreceived.
62 //
63 // keepyourselfregisterdwiththereator
64 return 0 ;
65 }
66
67 int handle_close(ACE_HANDLEh,ACE_Reactor_Maskm)
68 {
69 delete this ;
70 return 0 ;
71 }
72
73 // Usedbythereactortodeterminetheunderlyinghandle
74 ACE_HANDLEget_handle() const
75 {
76 return this -> peer_.get_handle();
77 }
78
79 // Returnsareferencetotheunderlyingstream.
80 ACE_SOCK_Stream & peer()
81 {
82 return this -> peer_;
83 }
84
85 private :
86 ACE_SOCK_Streampeer_;
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 // Openthepeer_acceptorsoitstartsto"listen"
100 // forincomingclients
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 // Overloadthehandleinputmethod
109 int handle_input(ACE_HANDLEhandle)
110 {
111 // Clienthasrequestedconnectiontoserver.
112 // Createahandlertohandletheconnection
113 Echo_Handler * eh;
114 ACE_NEW_RETURN(eh,Echo_Handler, - 1 );
115 ACE_INET_Addrcliaddr;
116 // Accepttheconnection"into"theEventHandler
117 if ( this -> peer_acceptor.accept(eh -> peer(), // stream
118 & cliaddr, // remoteaddress
119 0 , // timeout
120 1 ) == - 1 ) // restartifinterrupted
121 ACE_DEBUG((LM_ERROR, " Errorinconnection/n " ));
122
123 ACE_DEBUG((LM_DEBUG, " 连接已经建立,来自%s/n " ,cliaddr.get_host_addr()));
124
125 // Registertheinputeventhandlerforreading
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 // Usedbythereactortodeterminetheunderlyinghandle
133 ACE_HANDLEget_handle( void ) const
134 {
135 return this -> peer_acceptor.get_handle();
136 }
137 int handle_close(ACE_HANDLEh,ACE_Reactor_Maskm){
138 peer_acceptor.close();
139 delete this ;
140 return 0 ;
141 }
142
143 private :
144 Acceptorpeer_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_HANDLEh,ACE_Reactor_Maskm)
157 {
158 delete this ;
159 return 0 ;
160 }
161 virtual ~ Quit_Handler(){}
162 };
163 static ACE_THR_FUNC_RETURNrun_events( void * arg);
164 static ACE_THR_FUNC_RETURNcontroller( 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,THR_DETACHED | THR_SCOPE_SYSTEM) ==- 1 )
172 return 1 ;
173 return ACE_Thread_Manager::instance() -> wait();
174 }
175
176 static ACE_THR_FUNC_RETURNrun_events( void * arg)
177 {
178 ACE_Reactor * reactor = ACE_static_cast(ACE_Reactor * ,arg);
179 ACE_INET_Addraddr(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_RETURNcontroller( 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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom