一个高并发非阻塞的网络服务器例子

71 篇文章 3 订阅
64 篇文章 0 订阅
nginx, redis 服务器程序都是高并发非阻塞服务器程序的典型代表,acl 库的 C 库(lib_acl) 的 aio 模块设计了完整的非阻塞异步 IO 通信过程,在 acl 的C++库(lib_acl_cpp) 中封装并增强了异步通信的功能,本例子使用 lib_acl_cpp 中的非阻塞模块编写而成,功能虽然简单(支持定时器,回显功能),但却展示了非阻塞程序的编写过程,该例子是跨平台的(WIN32/LINUX/BSD/SOLARIS/MAC),支持 iocp/epoll/select/poll/devpoll/kqueue,本例子在 acl 库的位置:acl\lib_acl_cpp\samples\aio\aio_server
acl 库下载:http://sourceforge.net/projects/acl/
acl 库的 github:https://github.com/zhengshuxin/acl
更多技术文章:http://zsxxsz.iteye.com
标签: acl

代码片段(1)[全屏查看所有代码]

1. [代码][C/C++]代码     跳至 [1] [全屏预览]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#include <iostream>
#include <assert.h>
#include "lib_acl.h"
#include "acl_cpp/acl_cpp_init.hpp"
#include "acl_cpp/stream/aio_handle.hpp"
#include "acl_cpp/stream/aio_istream.hpp"
#include "acl_cpp/stream/aio_listen_stream.hpp"
#include "acl_cpp/stream/aio_socket_stream.hpp"
 
using namespace acl;
 
static int   __max = 0;
static int   __timeout = 0;
 
/**
  * 延迟读回调处理类
  */
class timer_reader: public aio_timer_reader
{
public :
     timer_reader( int delay)
     {
         delay_ = delay;
         std::cout << "timer_reader init, delay: " << delay << std::endl;
     }
 
     ~timer_reader()
     {
     }
 
     // aio_timer_reader 的子类必须重载 destroy 方法
     void destroy()
     {
         std::cout << "timer_reader delete, delay: "  << delay_ << std::endl;
         delete this ;
     }
 
     // 重载基类回调方法
     virtual void timer_callback(unsigned int id)
     {
         std::cout << "timer_reader(" << id
             << "): timer_callback, delay: " << delay_ << std::endl;
 
         // 调用基类的处理过程
         aio_timer_reader::timer_callback(id);
     }
 
private :
     int   delay_;
};
 
/**
  * 延迟写回调处理类
  */
class timer_writer: public aio_timer_writer
{
public :
     timer_writer( int delay)
     {
         delay_ = delay;
         std::cout << "timer_writer init, delay: " << delay << std::endl;
     }
 
     ~timer_writer()
     {
     }
 
     // aio_timer_reader 的子类必须重载 destroy 方法
     void destroy()
     {
         std::cout << "timer_writer delete, delay: " << delay_ << std::endl;
         delete this ;
     }
 
     // 重载基类回调方法
     virtual void timer_callback(unsigned int id)
     {
         std::cout << "timer_writer(" << id << "): timer_callback, delay: "
             << delay_ << std::endl;
 
         // 调用基类的处理过程
         aio_timer_writer::timer_callback(id);
     }
 
private :
     int   delay_;
};
 
/**
  * 异步客户端流的回调类的子类
  */
class io_callback : public aio_callback
{
public :
     io_callback(aio_socket_stream* client)
         : client_(client)
         , i_(0)
     {
     }
 
     ~io_callback()
     {
         std::cout << "delete io_callback now ..." << std::endl;
     }
 
     /**
      * 实现父类中的虚函数,客户端流的读成功回调过程
      * @param data {char*} 读到的数据地址
      * @param len {int} 读到的数据长度
      * @return {bool} 返回 true 表示继续,否则希望关闭该异步流
      */
     bool read_callback( char * data, int len)
     {
         i_++;
         if (i_ < 10)
             std::cout << ">>gets(i:" << i_ << "): "
                 << data << std::endl;
 
         // 如果远程客户端希望退出,则关闭之
         if (strncasecmp(data, "quit" , 4) == 0)
         {
             client_->format( "Bye!\r\n" );
             client_->close();
         }
 
         // 如果远程客户端希望服务端也关闭,则中止异步事件过程
         else if (strncasecmp(data, "stop" , 4) == 0)
         {
             client_->format( "Stop now!\r\n" );
             client_->close();  // 关闭远程异步流
 
             // 通知异步引擎关闭循环过程
             client_->get_handle().stop();
         }
 
         // 向远程客户端回写收到的数据
 
         int   delay = 0;
 
         if (strncasecmp(data, "write_delay" , strlen ( "write_delay" )) == 0)
         {
             // 延迟写过程
 
             const char * ptr = data + strlen ( "write_delay" );
             delay = atoi (ptr);
             if (delay > 0)
             {
                 std::cout << ">> write delay " << delay
                     << " second ..." << std::endl;
                 timer_writer* timer = new timer_writer(delay);
                 client_->write(data, len, delay * 1000000, timer);
                 client_-> gets (10, false );
                 return ( true );
             }
         }
         else if (strncasecmp(data, "read_delay" , strlen ( "read_delay" )) == 0)
         {
             // 延迟读过程
 
             const char * ptr = data + strlen ( "read_delay" );
             delay = atoi (ptr);
             if (delay > 0)
             {
                 client_->write(data, len);
                 std::cout << ">> read delay " << delay
                     << " second ..." << std::endl;
                 timer_reader* timer = new timer_reader(delay);
                 client_-> gets (10, false , delay * 1000000, timer);
                 return ( true );
             }
         }
 
         client_->write(data, len);
         //client_->gets(10, false);
         return ( true );
     }
 
     /**
      * 实现父类中的虚函数,客户端流的写成功回调过程
      * @return {bool} 返回 true 表示继续,否则希望关闭该异步流
      */
     bool write_callback()
     {
         return ( true );
     }
 
     /**
      * 实现父类中的虚函数,客户端流的超时回调过程
      */
     void close_callback()
     {
         // 必须在此处删除该动态分配的回调类对象以防止内存泄露
         delete this ;
     }
 
     /**
      * 实现父类中的虚函数,客户端流的超时回调过程
      * @return {bool} 返回 true 表示继续,否则希望关闭该异步流
      */
     bool timeout_callback()
     {
         std::cout << "Timeout, delete it ..." << std::endl;
         return ( false );
     }
 
private :
     aio_socket_stream* client_;
     int   i_;
};
 
/**
  * 异步监听流的回调类的子类
  */
class io_accept_callback : public aio_accept_callback
{
public :
     io_accept_callback() {}
     ~io_accept_callback()
     {
         printf ( ">>io_accept_callback over!\n" );
     }
 
     /**
      * 基类虚函数,当有新连接到达后调用此回调过程
      * @param client {aio_socket_stream*} 异步客户端流
      * @return {bool} 返回 true 以通知监听流继续监听
      */
     bool accept_callback(aio_socket_stream* client)
     {
         // 创建异步客户端流的回调对象并与该异步流进行绑定
         io_callback* callback = new io_callback(client);
 
         // 注册异步流的读回调过程
         client->add_read_callback(callback);
 
         // 注册异步流的写回调过程
         client->add_write_callback(callback);
 
         // 注册异步流的关闭回调过程
         client->add_close_callback(callback);
 
         // 注册异步流的超时回调过程
         client->add_timeout_callback(callback);
 
         // 当限定了行数据最大长度时
         if (__max > 0)
             client->set_buf_max(__max);
 
         // 从异步流读一行数据
         client-> gets (__timeout, false );
         return ( true );
     }
};
 
static void usage( const char * procname)
{
     printf ( "usage: %s -h[help]\r\n"
         "   -L line_max_length\r\n"
         "   -t timeout\r\n"
         "   -k[use kernel event: epoll/iocp/kqueue/devpool]\r\n" ,
         procname);
}
 
int main( int argc, char * argv[])
{
     bool use_kernel = false ;
     int  ch;
 
     while ((ch = getopt(argc, argv, "hkL:t:" )) > 0)
     {
         switch (ch)
         {
         case 'h' :
             usage(argv[0]);
             return (0);
         case 'k' :
             use_kernel = true ;
             break ;
         case 'L' :
             __max = atoi (optarg);
             break ;
         case 't' :
             __timeout = atoi (optarg);
             break ;
         default :
             break ;
         }
     }
 
     // 构建异步引擎类对象
     aio_handle handle(use_kernel ? ENGINE_KERNEL : ENGINE_SELECT);
 
     // 创建监听异步流
     aio_listen_stream* sstream = new aio_listen_stream(&handle);
     const char * addr = "127.0.0.1:9001" ;
 
     // 初始化ACL库(尤其是在WIN32下一定要调用此函数,在UNIX平台下可不调用)
     acl::acl_cpp_init();
 
     // 监听指定的地址
     if (sstream->open(addr) == false )
     {
         std::cout << "open " << addr << " error!" << std::endl;
         sstream->close();
         // XXX: 为了保证能关闭监听流,应在此处再 check 一下
         handle.check();
 
         getchar ();
         return (1);
     }
 
     // 创建回调类对象,当有新连接到达时自动调用此类对象的回调过程
     io_accept_callback callback;
     sstream->add_accept_callback(&callback);
     std::cout << "Listen: " << addr << " ok!" << std::endl;
 
     while ( true )
     {
         // 如果返回 false 则表示不再继续,需要退出
         if (handle.check() == false )
         {
             std::cout << "aio_server stop now ..." << std::endl;
             break ;
         }
     }
 
     // 关闭监听流并释放流对象
     sstream->close();
 
     // XXX: 为了保证能关闭监听流,应在此处再 check 一下
     handle.check();
 
     return (0);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值