forked from acl-dev/acl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsocket_stream.hpp
221 lines (193 loc) · 5.76 KB
/
socket_stream.hpp
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
#pragma once
#include "acl_cpp/acl_cpp_define.hpp"
#if defined(_WIN32) || defined(_WIN64)
#include <WinSock2.h>
#endif
#include "acl_cpp/stream/istream.hpp"
#include "acl_cpp/stream/ostream.hpp"
struct ACL_VSTREAM;
namespace acl {
class ACL_CPP_API socket_stream
: public istream
, public ostream
{
public:
socket_stream();
virtual ~socket_stream();
/**
* 根据套接字打开的一个网络流
* @param fd 套接字
* @return {bool} 连接是否成功
*/
#if defined(_WIN32) || defined(_WIN64)
bool open(SOCKET fd);
#else
bool open(int fd);
#endif
/**
* 根据 ACL_VSTREAM 流打开网络流
* @param vstream {ACL_VSTREAM*}
* @return {bool} 连接是否成功
*/
bool open(ACL_VSTREAM* vstream);
/**
* 连接远程服务器并打开网络连接流
* @param addr {const char*} 服务器地址, 若连接域套接口服务器(仅UNIX平台),
* 域套接地址:/tmp/test.sock; 如果连接一个TCP服务器,则地址格式为:
* [${local_ip}@]${remote_addr}, 如: [email protected]:80,
* 意思是绑定本的网卡地址为: 60.28.250.199, 远程连接 www.sina.com 的 80,
* 如果由OS自动绑定本地 IP 地址,则可以写为:www.sina.com:80
* @param conn_timeout {int} 连接超时时间(秒)
* @param rw_timeout {int} 读写超时时间(秒)
* @return {bool} 连接是否成功
*/
bool open(const char* addr, int conn_timeout, int rw_timeout);
/**
* 绑定本地 UDP 地址,创建 UDP 网络流对象
* @param addr {const char*} 本机地址,格式:ip:port
* @param rw_timeout {int} 读写超时时间(秒)
* @return {bool} 绑定是否成功
*/
bool bind_udp(const char* addr, int rw_timeout = 0);
/**
* 获得网络连接流的套接字连接句柄
* @return {ACL_SOCKET} 若出错,则返回 - 1(UNIX 平台)
* 或 INVALID_SOCKET(win32平台)
*/
#if defined(_WIN32) || defined(_WIN64)
SOCKET sock_handle() const;
#else
int sock_handle() const;
#endif
/**
* 解绑套接字与流对象的绑定关系,同时将套接字返回给用户,即
* 将该套接字的管理权交给用户,本流对象在释放时不会关闭该套
* 接字,但用户接管该套接字后用完后必须将其关闭
* 解绑后除了 close/open 的调用有意义外,其它的调用(包括流对
* 象读写在内)都无意义
* @return {ACL_SOCKET} 返回 ACL_SOCKET_INVALID 表示该流对象
* 已经将套接字解绑
*/
#if defined(_WIN32) || defined(_WIN64)
SOCKET unbind_sock();
#else
int unbind_sock();
#endif
/**
* 获得远程连接的地址
* @param full {bool} 是否获得完整地址,即:IP:PORT,如果该参数
* 为 false,则仅返回 IP,否则返回 IP:PORT
* @return {const char*} 远程连接地址,若返回值 == '\0' 则表示
* 无法获得远程连接地址
*/
const char* get_peer(bool full = false) const;
/**
* 获得远程连接的 IP 地址
* @return {const char*} 远程连接地址,若返回值 == '\0' 则表示
* 无法获得远程连接地址
*/
const char* get_peer_ip() const;
/**
* 设置远程连接对象的地址,对于 TCP 传输方式,不需要显示调用此函数
* 设置远程对象地址,UDP 传输方式时需要调用此函数设置远程地址,然后
* 才可以向远程连接写数据
* @param addr {const char*} 远程连接对象的地址,格式:ip:port
* @return {bool} 当流对象未打开时返回 false
*/
bool set_peer(const char* addr);
/**
* 获得连接的本地地址
* @param full {bool} 是否获得完整地址,即:IP:PORT,如果该参数
* 为 false,则仅返回 IP,否则返回 IP:PORT
* @return {const char*} 该连接的本地地址,若返回值 == "" 则表示
* 无法获得本地地址
*/
const char* get_local(bool full = false) const;
/**
* 获得连接的本地 IP 地址
* @return {const char*} 该连接的本地地址,若返回值 == "" 则表示
* 无法获得本地地址
*/
const char* get_local_ip() const;
/**
* 设置本地地址
* @param addr {const char*} 地址,格式:ip:port
* @return {bool} 当流对象未打开时返回 false
*/
bool set_local(const char* addr);
/**
* 检查套接口连接的存活状态(内部使用了非阻塞读的方式进行探测)
* @return {bool} 当网络连接未打开或已经关闭时该函数返回 false,如果
* 连接正常则返回 true
*/
bool alive() const;
/**
* 设置 TCP 套接字的 nodelay 功能
* @param on {bool} true 表示打开,false 表示关闭
* @return {socket_stream&}
*/
socket_stream& set_tcp_nodelay(bool on);
/**
* 设置 TCP 套接字的 SO_LINGER 选项
* @param on {bool} 是否启用 SO_LINGER 选项
* @param linger {int} 当SO_LINGER打开时,取消 timed_wait 的时间,单位为秒
* @return {socket_stream&}
*/
socket_stream& set_tcp_solinger(bool on, int linger);
/**
* 设置 TCP 套接字的写缓冲区大小
* @param size {int} 缓冲区设置大小
* @return {socket_stream&}
*/
socket_stream& set_tcp_sendbuf(int size);
/**
* 设置 TCP 套接字的读缓冲区大小
* @param size {int} 缓冲区设置大小
* @return {socket_stream&}
*/
socket_stream& set_tcp_recvbuf(int size);
/**
* 设置 TCP 套接字的非阻塞状态
* @param on {bool} 是否设置为非阻塞状态,当为 true 时,
* 则该套接字被设为非阻塞状态;否则为阻塞状态
* @return {socket_stream&}
*/
socket_stream& set_tcp_non_blocking(bool on);
/**
* 获得 TCP 套接字是否设置了 nodelay 选项
* @return {bool} true 表示打开,false 表示关闭
*/
bool get_tcp_nodelay();
/**
* 获得 TCP 套接字的 linger 值
* @param fd {ACL_SOCKET} 套接字
* @return {int} 返回 -1 表示未设置 linger 选项或内部出错,>= 0
* 表示设置了 linger 选项且该值表示套接字关闭后该 TCP 连接在内核中
* 维持 TIME_WAIT 状态的逗留时间(秒)
*/
int get_tcp_solinger();
/**
* 获取 TCP 套接字的写缓冲区大小
* @param fd {ACL_SOCKET} 套接字
* @return {int} 缓冲区大小
*/
int get_tcp_sendbuf();
/**
* 获取 TCP 套接字的读缓冲区大小
* @param fd {ACL_SOCKET} 套接字
* @return {int} 缓冲区大小
*/
int get_tcp_recvbuf();
/**
* 判断当前套接字是否被设置了非阻塞模式
* @return {bool}
* 注:该方法目前仅支持 UNIX 平台
*/
bool get_tcp_non_blocking();
private:
char dummy_[1];
char peer_ip_[33];
char local_ip_[33];
const char* get_ip(const char* addr, char* buf, size_t size);
};
} // namespace acl