-
Notifications
You must be signed in to change notification settings - Fork 0
/
HCPPSocket.h
421 lines (356 loc) · 8.8 KB
/
HCPPSocket.h
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
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
/***************************************************************
* Name: HCPPSocket.h
* Purpose: HCPPSocket接口,辅助套接字调用,套接字依赖操作系统实现.套接字事实上可移植性很好,大多数接口可在多种平台通用。在windows下需要链接ws2_32库。
* Author: HYH (hyhsystem.cn)
* Created: 2024-09-15
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HCPPSOCKET_H__
#define __HCPPSOCKET_H__
#if defined(__unix__) || defined(__linux__)
#ifndef HCPPSOCKET_HAVE_SOCKET
#define HCPPSOCKET_HAVE_SOCKET 1
#endif
#ifndef HCPPSOCKET_HAVE_SOCKET_IPV4
#define HCPPSOCKET_HAVE_SOCKET_IPV4 1
#endif
#ifndef HCPPSOCKET_HAVE_SOCKET_IPV6
#define HCPPSOCKET_HAVE_SOCKET_IPV6 1
#endif
#ifndef HCPPSOCKET_HAVE_SOCKET_UNIX
#define HCPPSOCKET_HAVE_SOCKET_UNIX 1
#endif
#endif
#ifdef WIN32
#ifndef HCPPSOCKET_HAVE_SOCKET
#define HCPPSOCKET_HAVE_SOCKET 1
#endif
#ifndef HCPPSOCKET_HAVE_SOCKET_IPV4
#define HCPPSOCKET_HAVE_SOCKET_IPV4 1
#endif
#ifndef HCPPSOCKET_HAVE_SOCKET_IPV6
#define HCPPSOCKET_HAVE_SOCKET_IPV6 1
#endif
#endif
#ifdef HCPPSOCKET_HAVE_SOCKET
/*
* unix/linux头文件
*/
#if defined(__unix__) || defined(__linux__)
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <strings.h>
#include <sys/socket.h>
#include <unistd.h>
#if defined(__unix__)
#include "sys/stat.h"
#include "sys/un.h"
#endif
#endif
/*
* windows头文件
*/
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
/*
* qnx头文件
*/
#ifdef __QNX__
#include <net/netbyte.h>
#endif
/*
* POSIX头文件
*/
#ifndef HCPPSOCKET_NO_POSIX
#include "fcntl.h"
#endif
/*
* 公共头文件(C/C++标准库)
*/
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
#include <functional>
#endif
/*
* 套接字,通常使用此类型定义一个套接字
*/
#ifndef SOCKET
#define SOCKET int
#endif
/*
* 无效套接字,当SOCKET类型的变量等于无效套接字时,表示套接字无效,可用初始化SOCKET类型的变量
*/
#ifndef INVALID_SOCKET
#define INVALID_SOCKET (-1)
#endif
/** \brief 套接字初始化,本函数可多次调用,无需反初始化(采用全局变量的构造及析构进行相关操作,本函数主要用于确保相关全局变量被链接进可执行文件)
*
* \return void* 返回套接字管理器地址
*
*/
#ifdef __cplusplus
extern "C"
{
#endif
void *HCPPSocketInit();
#ifdef __cplusplus
}
#endif
/*
* 套接字地址,此地址一般不直接使用,一般由具体的套接字地址(HCPPSocketAddress*)指针转化为本类型的指针(其作用类似void*)调用API(如bind)
*/
typedef struct sockaddr HCPPSocketAddress;
/*
* 套接字地址长度
*/
typedef socklen_t HCPPSocketAddressLength;
/*
* 地址大小默认为16字节
*/
#define HCPPSOCKETADDRESS_MAX_LENGTH sizeof(HCPPSocketAddress)
#ifdef HCPPSOCKET_HAVE_SOCKET_IPV4
/*
* IPV4套接字地址,可转化为HCPPSocketAddress*;
*/
typedef struct sockaddr_in HCPPSocketAddressIPV4;
/*
* 地址大小默认为16字节
*/
#undef HCPPSOCKETADDRESS_MAX_LENGTH
#define HCPPSOCKETADDRESS_MAX_LENGTH (sizeof(HCPPSocketAddressIPV4))
/*
* 通过主机名查询ip(IPV4)地址,通常用于connect
*/
#ifdef __cplusplus
extern "C"
{
#endif
bool HCPPSocketNslookup(const char* hostname, void (*reslut)(const char* hostname,const char *addr_string,HCPPSocketAddressIPV4* addr,void *usr),void *usr);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
bool HCPPSocketNslookup(const char* hostname, std::function<void (const char*, const char*, HCPPSocketAddressIPV4*,void *)> result,void *usr);
#endif
#endif
#ifdef HCPPSOCKET_HAVE_SOCKET_IPV6
/*
* IPV6套接字地址,可转化为HCPPSocketAddress*;
*/
typedef struct sockaddr_in6 HCPPSocketAddressIPV6;
/*
* 地址大小默认为28字节
*/
#undef HCPPSOCKETADDRESS_MAX_LENGTH
#define HCPPSOCKETADDRESS_MAX_LENGTH (sizeof(HCPPSocketAddressIPV6))
/*
* 通过主机名查询ip(IPV6)地址,通常用于connect
*/
#ifdef __cplusplus
extern "C"
{
#endif
bool HCPPSocketNslookup6(const char* hostname, void (*reslut)(const char* hostname, const char* addr_string, HCPPSocketAddressIPV6* addr, void* usr), void* usr);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
bool HCPPSocketNslookup6(const char* hostname, std::function<void(const char*, const char*, HCPPSocketAddressIPV6*, void*)> result, void* usr);
#endif
#endif
#ifdef HCPPSOCKET_HAVE_SOCKET_UNIX
/*
* UNIX套接字(文件)地址,可转化为HCPPSocketAddress*;
*/
typedef struct sockaddr_un HCPPSocketAddressUNIX;
/*
* 地址大小默认为110字节
*/
#undef HCPPSOCKETADDRESS_MAX_LENGTH
#define HCPPSOCKETADDRESS_MAX_LENGTH (sizeof(HCPPSocketAddressUNIX))
#endif
#ifdef __cplusplus
/*
* 自动套接字地址,可用于通用API编写,但可能浪费部分内存空间(会使用占用空间最大的套接字地址长度)
*/
class HCPPSocketAddressAuto
{
struct
{
int8_t pad[HCPPSOCKETADDRESS_MAX_LENGTH];
} addr;
public:
HCPPSocketAddressAuto()
{
memset(&addr,0,sizeof(addr));
}
HCPPSocketAddressAuto(HCPPSocketAddressAuto &oths):addr(oths.addr)
{
}
HCPPSocketAddressAuto(HCPPSocketAddressAuto &&oths):addr(oths.addr)
{
}
HCPPSocketAddressAuto & operator =(HCPPSocketAddressAuto &oths)
{
if(&oths!=this)
{
addr=oths.addr;
}
return *this;
}
HCPPSocketAddressAuto & operator =(HCPPSocketAddressAuto &&oths)
{
if(&oths!=this)
{
addr=oths.addr;
}
return *this;
}
virtual ~HCPPSocketAddressAuto()
{
}
operator HCPPSocketAddress *()
{
return (HCPPSocketAddress *)(void *)addr.pad;
}
HCPPSocketAddressAuto(HCPPSocketAddress &_addr)
{
memset(&addr,0,sizeof(addr));
memcpy(&addr,&_addr,sizeof(_addr));
}
HCPPSocketAddressAuto(HCPPSocketAddress &&_addr)
{
memset(&addr,0,sizeof(addr));
memcpy(&addr,&_addr,sizeof(_addr));
}
#ifdef HCPPSOCKET_HAVE_SOCKET_IPV4
operator HCPPSocketAddressIPV4 *()
{
if(((HCPPSocketAddress *)(*this))->sa_family==AF_INET)
{
return (HCPPSocketAddressIPV4 *)(void *)addr.pad;
}
else
{
return NULL;
}
}
HCPPSocketAddressAuto(HCPPSocketAddressIPV4 &_addr)
{
memset(&addr,0,sizeof(addr));
memcpy(&addr,&_addr,sizeof(_addr));
}
HCPPSocketAddressAuto(HCPPSocketAddressIPV4 &&_addr)
{
memset(&addr,0,sizeof(addr));
memcpy(&addr,&_addr,sizeof(_addr));
}
#endif
#ifdef HCPPSOCKET_HAVE_SOCKET_IPV6
operator HCPPSocketAddressIPV6 *()
{
if(((HCPPSocketAddress *)(*this))->sa_family==AF_INET6)
{
return (HCPPSocketAddressIPV6 *)(void *)addr.pad;
}
else
{
return NULL;
}
}
HCPPSocketAddressAuto(HCPPSocketAddressIPV6 &_addr)
{
memset(&addr,0,sizeof(addr));
memcpy(&addr,&_addr,sizeof(_addr));
}
HCPPSocketAddressAuto(HCPPSocketAddressIPV6 &&_addr)
{
memset(&addr,0,sizeof(addr));
memcpy(&addr,&_addr,sizeof(_addr));
}
#endif
#ifdef HCPPSOCKET_HAVE_SOCKET_UNIX
operator HCPPSocketAddressUNIX *()
{
if(((HCPPSocketAddress *)(*this))->sa_family==AF_UNIX)
{
return (HCPPSocketAddressUNIX *)(void *)addr.pad;
}
else
{
return NULL;
}
}
HCPPSocketAddressAuto(HCPPSocketAddressUNIX &_addr)
{
memset(&addr,0,sizeof(addr));
memcpy(&addr,&_addr,sizeof(_addr));
}
HCPPSocketAddressAuto(HCPPSocketAddressUNIX &&_addr)
{
memset(&addr,0,sizeof(addr));
memcpy(&addr,&_addr,sizeof(_addr));
}
#endif
HCPPSocketAddressLength Length()
{
HCPPSocketAddressLength len=sizeof(addr);
switch(((HCPPSocketAddress *)(*this))->sa_family)
{
#ifdef HCPPSOCKET_HAVE_SOCKET_IPV4
case AF_INET:
{
len=sizeof(HCPPSocketAddressIPV4);
}
break;
#endif
#ifdef HCPPSOCKET_HAVE_SOCKET_IPV6
case AF_INET6:
{
len=sizeof(HCPPSocketAddressIPV6);
}
break;
#endif
#ifdef HCPPSOCKET_HAVE_SOCKET_UNIX
case AF_UNIX:
{
len=sizeof(HCPPSocketAddressUNIX);
}
break;
#endif
default:
break;
}
return len;
}
operator HCPPSocketAddressLength()
{
return Length();
}
};
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef WIN32
/*
* 关闭套接字,通常用于兼容windows下的代码
*/
int closesocket(SOCKET s);
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif // __HCPPSOCKET_H__