acl  3.5.3.0
server_socket.hpp
浏览该文件的文档.
1 #pragma once
2 #include "../acl_cpp_define.hpp"
3 #include "../stdlib/string.hpp"
4 #include "../stdlib/noncopyable.hpp"
5 #if defined(_WIN32) || defined(_WIN64)
6 #include <WinSock2.h>
7 #endif
8 
9 namespace acl {
10 
11 class socket_stream;
12 
13 enum {
15  OPEN_FLAG_NONBLOCK = 1, // 非阻塞模式
16  OPEN_FLAG_REUSEPORT = 1 << 1, // 端口复用,要求 Linux3.0 以上
17  OPEN_FLAG_EXCLUSIVE = 1 << 2, // 是否禁止复用地址
18 };
19 
20 /**
21  * 服务端监听套接口类,接收客户端连接,并创建客户端流连接对象
22  */
24 {
25 public:
26 #if 0
27  /**
28  * 构造函数,调用本构造函数后需调用类方法 open 来监听指定服务地址
29  * @param backlog {int} 监听套接口队列长度
30  * @param block {bool} 是阻塞模式还是非阻塞模式
31  */
32  server_socket(int backlog, bool block);
33 #endif
34 
35  /**
36  * 构造函数
37  * @param flag {unsigned} 定义参见 OPEN_FLAG_XXX
38  * @param backlog {int} 监听套接口队列长度
39  */
40  server_socket(unsigned flag, int backlog);
41 
42  /**
43  * 构造函数,调用本构造函数后禁止再调用 open 方法
44  * @param sstream {ACL_VSTREAM*} 外部创建的监听流对象,本类仅使用
45  * 但并不释放,由应用自行关闭该监听对象
46  */
47  server_socket(ACL_VSTREAM* sstream);
48 
49  /**
50  * 构造函数,调用本构造函数后禁止再调用 open 方法
51  * @param fd {ACL_SOCKET} 外部创建的监听句柄,本类仅使用但并不释放,
52  * 由应用自行关闭该监听句柄
53  */
54 #if defined(_WIN32) || defined(_WIN64)
55  server_socket(SOCKET fd);
56 #else
57  server_socket(int fd);
58 #endif
59 
60  server_socket(void);
61  ~server_socket(void);
62 
63  /**
64  * 开始监听给定服务端地址
65  * @param addr {const char*} 服务器监听地址,格式为:
66  * ip:port;在 unix 环境下,还可以是域套接口,格式为:/path/xxx,在
67  * Linux 平台下,如果域套接口地址为:@xxx 格式,即第一个字母为 @ 则
68  * 内部自动启用 Linux 下的抽象域套接字方式(abstract unix socket)
69  * @return {bool} 监听是否成功
70  */
71  bool open(const char* addr);
72 
73  /**
74  * 判断当前监听套接口是否打开着
75  * @return {bool}
76  */
77  bool opened(void) const;
78 
79  /**
80  * 关闭已经打开的监听套接口
81  * @return {bool} 是否正常关闭
82  */
83  bool close(void);
84 
85  /**
86  * 将监听套接口从服务监听对象中解绑
87  * @return {SOCKET} 返回被解绑的句柄
88  */
89 #if defined(_WIN32) || defined(_WIN64)
90  SOCKET unbind(void);
91 #else
92  int unbind(void);
93 #endif
94 
95  /**
96  * 接收客户端连接并创建客户端连接流
97  * @param timeout {int} 当该值 > 0 时,采用超时方式接收客户端连接,
98  * 若在指定时间内未获得客户端连接,则返回 NULL
99  * @param etimed {bool*} 当此指针非 NULL 时,如果因超时导致该函数返回
100  * NULL,则此值被置为 true
101  * @return {socket_stream*} 返回空表示接收失败或超时
102  */
103  socket_stream* accept(int timeout = 0, bool* etimed = NULL);
104 
105  /**
106  * 获得监听的地址
107  * @return {const char*} 返回值非空指针
108  */
109  const char* get_addr(void) const
110  {
111  return addr_.c_str();
112  }
113 
114  /**
115  * 当正常监听服务器地址后调用本函数可以获得监听套接口
116  * @return {int}
117  */
118 #if defined(_WIN32) || defined(_WIN64)
119  SOCKET sock_handle(void) const
120 #else
121  int sock_handle(void) const
122 #endif
123  {
124  return fd_;
125  }
126 
127  /**
128  * 设置监听套接字的延迟接收功能,即当客户端连接上有数据时才将该连接返回
129  * 给应用,目前该功能仅支持 Linux
130  * @param timeout {int} 如果客户端连接在规定的时间内未发来数据,
131  * 也将该连接返回给应用
132  */
133  void set_tcp_defer_accept(int timeout);
134 
135 private:
136  int backlog_;
137  unsigned open_flag_;
138  bool unix_sock_;
139  string addr_;
140 
141 #if defined(_WIN32) || defined(_WIN64)
142  SOCKET fd_;
143  SOCKET fd_local_;
144 #else
145  int fd_;
146  int fd_local_;
147 #endif
148 };
149 
150 } // namespace acl
const char * get_addr(void) const
int sock_handle(void) const
#define ACL_CPP_API