acl  3.5.3.0
aio_listen_stream.hpp
浏览该文件的文档.
1 #pragma once
2 #include "../acl_cpp_define.hpp"
3 #include "aio_stream.hpp"
4 
5 namespace acl
6 {
7 
8 class aio_socket_stream;
9 class aio_listen_stream;
10 
11 /**
12  * 当异步监听流接收到新的客户端流时调用此回调类中的回调函数,该类为纯虚类,
13  * 要求子类必须实现 accept_callback 回调过程
14  */
16 {
17 public:
19  virtual ~aio_accept_callback(void) {}
20 
21  /**
22  * 当接收到新的客户端流时的回调函数
23  * @param client {aio_socket_stream*} 客户端异步连接流,
24  * 可以对此流进行读写操作
25  * @return {bool} 如果希望关闭该异步监听流,可以返回 false,
26  * 一般不应返回 false
27  */
28  virtual bool accept_callback(aio_socket_stream* client) = 0;
29 };
30 
31 /**
32  * 当异步监听流收到有新连接到达事件时调用此类中的虚函数,在由子类实现该虚函数
33  * 中调用 accept() 系统 API 接收客户端连接,该类与上面的 aio_accept_callback
34  * 有所不同,在 aio_accept_callback::accept_callback() 被调用时,客户端连接对
35  * 象已经被创建,而在 listen_callback() 中,则需要应用自己接收连接对象
36  */
38 {
39 public:
41  virtual ~aio_listen_callback(void) {}
42 
43  virtual bool listen_callback(aio_listen_stream& ss) = 0;
44 };
45 
46 /**
47  * 异步监听网络流,该类接收来自于客户端的外来连接,同时该类只能
48  * 在堆上分配,不能在栈分配,应用可以调用 close 主动关闭流,流关闭
49  * 后该异步流对象自动释放,无需调用 delete 删除该类对象
50  *
51  */
53 {
54 public:
55  /**
56  * 构造函数,用以构造异步监听流
57  * @param handle {aio_handle*} 异步引擎句柄
58  */
60 
61  /**
62  * 添加异步监听流接收到新客户端流时的回调函数
63  * @param callback {aio_accept_callback*}
64  */
65  void add_accept_callback(aio_accept_callback* callback);
66 
67  /**
68  * 添加异步监听流有客户端连接到达时的回调函数
69  * @param callback {aio_listen_stream*}
70  * 注意:本方法与上面 add_accept_callback 的区别,本方法是 reactor
71  * 模式,而 add_accept_callback 则是 proactor 模式
72  */
73  void add_listen_callback(aio_listen_callback* callback);
74 
75  /**
76  * 当调用 add_listen_callback 方式时,在 aio_listen_callback 子类
77  * 中的函数 listen_callback 里可以调用本方法来获得一个异步连接对象
78  * @return {aio_socket_stream*} 返回 NULL 表示获得连接失败
79  */
80  aio_socket_stream* accept(void);
81 
82  /**
83  * 开始监听某个指定地址,可以为网络套接口,也可以为域套接口,
84  * @param addr {const char*} 监听地址,TCP监听地址或域监听地址
85  * 格式:
86  * 针对TCP连接:IP:PORT,如:127.0.0.1:9001
87  * 针对域套接口:{path},如:/tmp/my.sock,在 Linux 平台,还可以支持
88  * Linux abstract unix domain socket,需要地址首字节为'@',在 Linux
89  * 平台下,acl 内部如果检测到路径首字节为 '@',则内部自动切到 Linux
90  * abstract unix domain socket 监听模式(其中的 @ 符只是用来标记,内
91  * 部的监听地址会自动去掉)
92  * @param flag {unsigned} 创建监听套接口时的打开标志位,见 server_socket.hpp
93  * @return {bool} 监听是否成功
94  */
95  bool open(const char* addr, unsigned flag = 0);
96 
97  /**
98  * 使用套接字创建监听对象,该套接字句柄必须已经调用了 bind/listen 过程
99  * @param fd {int}
100  * @return {bool} 是否成功
101  */
102 #if defined(_WIN32) || defined(_WIN64)
103  bool open(SOCKET fd);
104 #else
105  bool open(int fd);
106 #endif
107 
108  /**
109  * 使用同步流对象创建非阻塞监听对象
110  * @param vstream {ACL_VSTREAM*} 非空对象
111  * @return {bool} 是否成功
112  */
113  bool open(ACL_VSTREAM* vstream);
114 
115  /**
116  * 使用非阻塞流对象创建非阻塞监听对象
117  * @param astream {ACL_ASTREAM*} 非空对象
118  * @return {bool} 是否成功
119  */
120  bool open(ACL_ASTREAM* astream);
121 
122  /**
123  * 获得服务器监听地址
124  * @return {const char*}
125  */
126  const char* get_addr(void) const;
127 
128  /**
129  * 重载基类方法,当异步流对象销毁时回调此方法
130  */
131  virtual void destroy(void);
132 
133 protected:
134  virtual ~aio_listen_stream(void);
135 
136 private:
137  bool listen_hooked_;
138  char addr_[256];
139  std::list<aio_accept_callback*> accept_callbacks_;
140  std::list<aio_listen_callback*> listen_callbacks_;
141 
142  void hook_listen(void);
143  int accept_callback(aio_socket_stream* conn);
144  static int listen_callback(ACL_ASTREAM*, void*);
145 };
146 
147 } // namespace acl
#define ACL_CPP_API