SocketHelper.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Author : Bruce Liang
  5. * Website : https://github.com/ldcsaa
  6. * Project : https://github.com/ldcsaa/HP-Socket
  7. * Blog : http://www.cnblogs.com/ldcsaa
  8. * Wiki : http://www.oschina.net/p/hp-socket
  9. * QQ Group : 44636872, 75375912
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. #pragma once
  24. #include "hpsocket/HPTypeDef.h"
  25. #include "hpsocket/SocketInterface.h"
  26. #include "common/StringT.h"
  27. #include "common/SysHelper.h"
  28. #include "common/BufferPtr.h"
  29. #include "common/BufferPool.h"
  30. #include "common/RingBuffer.h"
  31. #include "common/FileHelper.h"
  32. #include "InternalDef.h"
  33. #include <netdb.h>
  34. #include <sys/un.h>
  35. #include <sys/socket.h>
  36. #include <arpa/inet.h>
  37. #ifdef _ZLIB_SUPPORT
  38. #include <zlib.h>
  39. #endif
  40. #ifdef _BROTLI_SUPPORT
  41. #include <brotli/decode.h>
  42. #include <brotli/encode.h>
  43. #endif
  44. using ADDRESS_FAMILY = sa_family_t;
  45. using IN_ADDR = in_addr;
  46. using IN6_ADDR = in6_addr;
  47. using SOCKADDR = sockaddr;
  48. using SOCKADDR_IN = sockaddr_in;
  49. using SOCKADDR_IN6 = sockaddr_in6;
  50. typedef struct hp_addr
  51. {
  52. ADDRESS_FAMILY family;
  53. union
  54. {
  55. ULONG_PTR addr;
  56. IN_ADDR addr4;
  57. IN6_ADDR addr6;
  58. };
  59. static const hp_addr ANY_ADDR4;
  60. static const hp_addr ANY_ADDR6;
  61. inline int AddrSize() const
  62. {
  63. return AddrSize(family);
  64. }
  65. inline static int AddrSize(ADDRESS_FAMILY f)
  66. {
  67. if(f == AF_INET)
  68. return sizeof(IN_ADDR);
  69. return sizeof(IN6_ADDR);
  70. }
  71. inline static const hp_addr& AnyAddr(ADDRESS_FAMILY f)
  72. {
  73. if(f == AF_INET)
  74. return ANY_ADDR4;
  75. return ANY_ADDR6;
  76. }
  77. inline const ULONG_PTR* Addr() const {return &addr;}
  78. inline ULONG_PTR* Addr() {return &addr;}
  79. inline BOOL IsIPv4() const {return family == AF_INET;}
  80. inline BOOL IsIPv6() const {return family == AF_INET6;}
  81. inline BOOL IsSpecified() const {return IsIPv4() || IsIPv6();}
  82. inline void ZeroAddr() {::ZeroMemory(&addr6, sizeof(addr6));}
  83. inline void Reset() {::ZeroMemory(this, sizeof(*this));}
  84. inline hp_addr& Copy(hp_addr& other) const
  85. {
  86. if(this != &other)
  87. memcpy(&other, this, offsetof(hp_addr, addr) + AddrSize());
  88. return other;
  89. }
  90. hp_addr(ADDRESS_FAMILY f = AF_UNSPEC, BOOL bZeroAddr = FALSE)
  91. {
  92. family = f;
  93. if(bZeroAddr) ZeroAddr();
  94. }
  95. } HP_ADDR, *HP_PADDR;
  96. typedef struct hp_sockaddr
  97. {
  98. union
  99. {
  100. ADDRESS_FAMILY family;
  101. SOCKADDR addr;
  102. SOCKADDR_IN addr4;
  103. SOCKADDR_IN6 addr6;
  104. };
  105. inline int AddrSize() const
  106. {
  107. return AddrSize(family);
  108. }
  109. inline static int AddrSize(ADDRESS_FAMILY f)
  110. {
  111. if(f == AF_INET)
  112. return sizeof(SOCKADDR_IN);
  113. return sizeof(SOCKADDR_IN6);
  114. }
  115. inline int EffectAddrSize() const
  116. {
  117. return EffectAddrSize(family);
  118. }
  119. inline static int EffectAddrSize(ADDRESS_FAMILY f)
  120. {
  121. return (f == AF_INET) ? offsetof(SOCKADDR_IN, sin_zero) : sizeof(SOCKADDR_IN6);
  122. }
  123. inline static const hp_sockaddr& AnyAddr(ADDRESS_FAMILY f)
  124. {
  125. static const hp_sockaddr s_any_addr4(AF_INET, TRUE);
  126. static const hp_sockaddr s_any_addr6(AF_INET6, TRUE);
  127. if(f == AF_INET)
  128. return s_any_addr4;
  129. return s_any_addr6;
  130. }
  131. inline static int AddrMinStrLength(ADDRESS_FAMILY f)
  132. {
  133. if(f == AF_INET)
  134. return INET_ADDRSTRLEN;
  135. return INET6_ADDRSTRLEN;
  136. }
  137. inline BOOL IsIPv4() const {return family == AF_INET;}
  138. inline BOOL IsIPv6() const {return family == AF_INET6;}
  139. inline BOOL IsSpecified() const {return IsIPv4() || IsIPv6();}
  140. inline USHORT Port() const {return ntohs(addr4.sin_port);}
  141. inline void SetPort(USHORT usPort) {addr4.sin_port = htons(usPort);}
  142. inline void* SinAddr() const {return IsIPv4() ? (void*)&addr4.sin_addr : (void*)&addr6.sin6_addr;}
  143. inline void* SinAddr() {return IsIPv4() ? (void*)&addr4.sin_addr : (void*)&addr6.sin6_addr;}
  144. inline const SOCKADDR* Addr() const {return &addr;}
  145. inline SOCKADDR* Addr() {return &addr;}
  146. inline void ZeroAddr() {::ZeroMemory(((char*)this) + sizeof(family), sizeof(*this) - sizeof(family));}
  147. inline void Reset() {::ZeroMemory(this, sizeof(*this));}
  148. inline hp_sockaddr& Copy(hp_sockaddr& other) const
  149. {
  150. if(this != &other)
  151. memcpy(&other, this, AddrSize());
  152. return other;
  153. }
  154. size_t Hash() const
  155. {
  156. ASSERT(IsSpecified());
  157. size_t _Val = 2166136261U;
  158. const int size = EffectAddrSize();
  159. const BYTE* pAddr = (const BYTE*)Addr();
  160. for(int i = 0; i < size; i++)
  161. _Val = 16777619U * _Val ^ (size_t)pAddr[i];
  162. return (_Val);
  163. }
  164. bool EqualTo(const hp_sockaddr& other) const
  165. {
  166. ASSERT(IsSpecified() && other.IsSpecified());
  167. return EqualMemory(this, &other, EffectAddrSize());
  168. }
  169. hp_sockaddr(ADDRESS_FAMILY f = AF_UNSPEC, BOOL bZeroAddr = FALSE)
  170. {
  171. family = f;
  172. if(bZeroAddr) ZeroAddr();
  173. }
  174. } HP_SOCKADDR, *HP_PSOCKADDR;
  175. typedef struct hp_scope_host
  176. {
  177. LPCTSTR addr;
  178. LPCTSTR name;
  179. BOOL bNeedFree;
  180. hp_scope_host(LPCTSTR lpszOriginAddress)
  181. {
  182. ASSERT(lpszOriginAddress != nullptr);
  183. LPCTSTR lpszFind = ::StrChr(lpszOriginAddress, HOST_SEPARATOR_CHAR);
  184. if(lpszFind == nullptr)
  185. {
  186. addr = lpszOriginAddress;
  187. name = lpszOriginAddress;
  188. bNeedFree = FALSE;
  189. }
  190. else
  191. {
  192. int i = (int)(lpszFind - lpszOriginAddress);
  193. int iSize = (int)lstrlen(lpszOriginAddress) + 1;
  194. LPTSTR lpszCopy = new TCHAR[iSize];
  195. ::memcpy((PVOID)lpszCopy, (PVOID)lpszOriginAddress, iSize * sizeof(TCHAR));
  196. lpszCopy[i] = 0;
  197. addr = lpszCopy;
  198. name = lpszCopy + i + 1;
  199. bNeedFree = TRUE;
  200. if(::IsStrEmpty(name))
  201. name = addr;
  202. }
  203. }
  204. ~hp_scope_host()
  205. {
  206. if(bNeedFree)
  207. delete[] addr;
  208. }
  209. } HP_SCOPE_HOST, *HP_PSCOPE_HOST;
  210. struct TNodeBufferObj : public TItem
  211. {
  212. using __super = TItem;
  213. HP_SOCKADDR remoteAddr;
  214. public:
  215. void Reset(int first = 0, int last = 0)
  216. {
  217. __super::Reset(first, last);
  218. remoteAddr.Reset();
  219. }
  220. public:
  221. static TNodeBufferObj* Construct(CPrivateHeap& heap,
  222. int capacity = DEFAULT_ITEM_CAPACITY,
  223. BYTE* pData = nullptr,
  224. int length = 0)
  225. {
  226. return ::ConstructItemT((TNodeBufferObj*)(nullptr), heap, capacity, pData, length);
  227. }
  228. static void Destruct(TNodeBufferObj* pBufferObj)
  229. {
  230. ::DestructItemT(pBufferObj);
  231. }
  232. TNodeBufferObj(CPrivateHeap& hp, BYTE* pHead, int cap = DEFAULT_ITEM_CAPACITY, BYTE* pData = nullptr, int length = 0)
  233. : TItem(hp, pHead, cap, pData, length)
  234. {
  235. }
  236. ~TNodeBufferObj()
  237. {
  238. }
  239. DECLARE_NO_COPY_CLASS(TNodeBufferObj)
  240. };
  241. typedef TItemPtrT<TNodeBufferObj> TNodeBufferObjPtr;
  242. typedef CNodePoolT<TNodeBufferObj> CNodeBufferObjPool;
  243. typedef CCASQueue<TNodeBufferObj> CNodeRecvQueue;
  244. typedef TItemListExT<TNodeBufferObj, volatile int> TNodeBufferObjList;
  245. typedef unique_ptr<CCriSec[]> CNodeCriSecs;
  246. typedef unique_ptr<TNodeBufferObjList[]> TNodeBufferObjLists;
  247. /* Server 组件和 Agent 组件内部使用的事件处理结果常量 */
  248. // 连接已关闭
  249. #define HR_CLOSED 0xFF
  250. /* 命令类型 */
  251. enum EnDispCmdType
  252. {
  253. DISP_CMD_SEND = 0x01, // 发送数据
  254. DISP_CMD_RECEIVE = 0x02, // 接收数据
  255. DISP_CMD_UNPAUSE = 0x03, // 恢复接收数据
  256. DISP_CMD_DISCONNECT = 0x04, // 断开连接
  257. DISP_CMD_TIMEOUT = 0x05, // 保活超时
  258. };
  259. /* 关闭连接标识 */
  260. enum EnSocketCloseFlag
  261. {
  262. SCF_NONE = 0, // 不触发事件
  263. SCF_CLOSE = 1, // 触发 正常关闭 OnClose 事件
  264. SCF_ERROR = 2 // 触发 异常关闭 OnClose 事件
  265. };
  266. /* 监听 Socket 数组智能指针 */
  267. typedef unique_ptr<SOCKET[]> ListenSocketsPtr;
  268. /* 数据缓冲节点 */
  269. typedef TItem TBufferObj;
  270. /* 数据缓冲节点智能指针 */
  271. typedef TItemPtr TBufferObjPtr;
  272. /* 数据缓冲区对象池 */
  273. typedef CItemPool CBufferObjPool;
  274. /* 数据缓冲区链表模板 */
  275. typedef TItemListExV TBufferObjList;
  276. /* 接收缓冲区数组智能指针 */
  277. typedef unique_ptr<CBufferPtr[]> CReceiveBuffersPtr;
  278. /* 线程 ID - 接收缓冲区哈希表 */
  279. typedef unordered_map<THR_ID, CBufferPtr*> TReceiveBufferMap;
  280. /* 线程 ID - 接收缓冲区哈希表迭代器 */
  281. typedef TReceiveBufferMap::iterator TReceiveBufferMapI;
  282. /* 线程 ID - 接收缓冲区哈希表 const 迭代器 */
  283. typedef TReceiveBufferMap::const_iterator TReceiveBufferMapCI;
  284. /* Socket 缓冲区基础结构 */
  285. struct TSocketObjBase : public CSafeCounter
  286. {
  287. CPrivateHeap& heap;
  288. CReentrantCriSec csSend;
  289. TBufferObjList sndBuff;
  290. CONNID connID;
  291. HP_SOCKADDR remoteAddr;
  292. PVOID extra;
  293. PVOID reserved;
  294. PVOID reserved2;
  295. DWORD activeTime;
  296. union
  297. {
  298. DWORD freeTime;
  299. DWORD connTime;
  300. };
  301. volatile BOOL valid;
  302. volatile BOOL connected;
  303. volatile BOOL paused;
  304. TSocketObjBase(CPrivateHeap& hp, CBufferObjPool& bfPool) : heap(hp), sndBuff(bfPool) {}
  305. static BOOL IsExist(TSocketObjBase* pSocketObj)
  306. {return pSocketObj != nullptr;}
  307. static BOOL IsValid(TSocketObjBase* pSocketObj)
  308. {return (IsExist(pSocketObj) && pSocketObj->valid == TRUE);}
  309. static void Invalid(TSocketObjBase* pSocketObj)
  310. {ASSERT(IsExist(pSocketObj)); pSocketObj->valid = FALSE;}
  311. static void Release(TSocketObjBase* pSocketObj)
  312. {
  313. ASSERT(IsExist(pSocketObj));
  314. pSocketObj->freeTime = ::TimeGetTime();
  315. pSocketObj->sndBuff.Release();
  316. }
  317. static BOOL InvalidSocketObj(TSocketObjBase* pSocketObj)
  318. {
  319. BOOL bDone = FALSE;
  320. if(TSocketObjBase::IsValid(pSocketObj))
  321. {
  322. pSocketObj->SetConnected(FALSE);
  323. CReentrantCriSecLock locallock(pSocketObj->csSend);
  324. if(TSocketObjBase::IsValid(pSocketObj))
  325. {
  326. TSocketObjBase::Invalid(pSocketObj);
  327. bDone = TRUE;
  328. }
  329. }
  330. return bDone;
  331. }
  332. DWORD GetConnTime () const {return connTime;}
  333. DWORD GetFreeTime () const {return freeTime;}
  334. DWORD GetActiveTime () const {return activeTime;}
  335. BOOL IsPaused () const {return paused;}
  336. int Pending () const {return sndBuff.Length();}
  337. BOOL IsPending () const {return Pending() > 0;}
  338. BOOL HasConnected() {return connected == TRUE;}
  339. BOOL IsConnecting() {return connected == CST_CONNECTING;}
  340. void SetConnected(BOOL bConnected = TRUE) {connected = bConnected;}
  341. void Reset(CONNID dwConnID)
  342. {
  343. ResetCount();
  344. connID = dwConnID;
  345. connected = FALSE;
  346. valid = TRUE;
  347. paused = FALSE;
  348. extra = nullptr;
  349. reserved = nullptr;
  350. reserved2 = nullptr;
  351. }
  352. };
  353. /* 数据缓冲区结构 */
  354. struct TSocketObj : public TSocketObjBase
  355. {
  356. using __super = TSocketObjBase;
  357. SOCKET socket;
  358. static TSocketObj* Construct(CPrivateHeap& hp, CBufferObjPool& bfPool)
  359. {
  360. TSocketObj* pSocketObj = (TSocketObj*)hp.Alloc(sizeof(TSocketObj));
  361. ASSERT(pSocketObj);
  362. return new (pSocketObj) TSocketObj(hp, bfPool);
  363. }
  364. static void Destruct(TSocketObj* pSocketObj)
  365. {
  366. ASSERT(pSocketObj);
  367. CPrivateHeap& heap = pSocketObj->heap;
  368. pSocketObj->TSocketObj::~TSocketObj();
  369. heap.Free(pSocketObj);
  370. }
  371. TSocketObj(CPrivateHeap& hp, CBufferObjPool& bfPool)
  372. : __super(hp, bfPool)
  373. {
  374. }
  375. void Reset(CONNID dwConnID, SOCKET soClient)
  376. {
  377. __super::Reset(dwConnID);
  378. socket = soClient;
  379. }
  380. };
  381. /* Agent 数据缓冲区结构 */
  382. struct TAgentSocketObj : public TSocketObj
  383. {
  384. using __super = TSocketObj;
  385. CStringA host;
  386. static TAgentSocketObj* Construct(CPrivateHeap& hp, CBufferObjPool& bfPool)
  387. {
  388. TAgentSocketObj* pSocketObj = (TAgentSocketObj*)hp.Alloc(sizeof(TAgentSocketObj));
  389. ASSERT(pSocketObj);
  390. return new (pSocketObj) TAgentSocketObj(hp, bfPool);
  391. }
  392. static void Destruct(TAgentSocketObj* pSocketObj)
  393. {
  394. ASSERT(pSocketObj);
  395. CPrivateHeap& heap = pSocketObj->heap;
  396. pSocketObj->TAgentSocketObj::~TAgentSocketObj();
  397. heap.Free(pSocketObj);
  398. }
  399. TAgentSocketObj(CPrivateHeap& hp, CBufferObjPool& bfPool)
  400. : __super(hp, bfPool)
  401. {
  402. }
  403. void Reset(CONNID dwConnID, SOCKET soClient)
  404. {
  405. __super::Reset(dwConnID, soClient);
  406. host.Empty();
  407. }
  408. BOOL GetRemoteHost(LPCSTR* lpszHost, USHORT* pusPort = nullptr)
  409. {
  410. *lpszHost = host;
  411. if(pusPort)
  412. *pusPort = remoteAddr.Port();
  413. return (!host.IsEmpty());
  414. }
  415. };
  416. /* UDP 数据缓冲区结构 */
  417. struct TUdpSocketObj : public TSocketObjBase
  418. {
  419. using __super = TSocketObjBase;
  420. int index;
  421. PVOID pHolder;
  422. FD fdTimer;
  423. volatile DWORD detectFails;
  424. static TUdpSocketObj* Construct(CPrivateHeap& hp, CBufferObjPool& bfPool)
  425. {
  426. TUdpSocketObj* pSocketObj = (TUdpSocketObj*)hp.Alloc(sizeof(TUdpSocketObj));
  427. ASSERT(pSocketObj);
  428. return new (pSocketObj) TUdpSocketObj(hp, bfPool);
  429. }
  430. static void Destruct(TUdpSocketObj* pSocketObj)
  431. {
  432. ASSERT(pSocketObj);
  433. CPrivateHeap& heap = pSocketObj->heap;
  434. pSocketObj->TUdpSocketObj::~TUdpSocketObj();
  435. heap.Free(pSocketObj);
  436. }
  437. TUdpSocketObj(CPrivateHeap& hp, CBufferObjPool& bfPool)
  438. : __super(hp, bfPool)
  439. {
  440. }
  441. void Reset(CONNID dwConnID)
  442. {
  443. __super::Reset(dwConnID);
  444. index = -1;
  445. detectFails = 0;
  446. fdTimer = INVALID_FD;
  447. pHolder = nullptr;
  448. }
  449. };
  450. /* 有效 TSocketObj 缓存 */
  451. typedef CRingCache2<TSocketObj, CONNID, true> TSocketObjPtrPool;
  452. /* 失效 TSocketObj 缓存 */
  453. typedef CRingPool<TSocketObj> TSocketObjPtrList;
  454. /* 失效 TSocketObj 垃圾回收结构链表 */
  455. typedef CCASQueue<TSocketObj> TSocketObjPtrQueue;
  456. /* 有效 TSocketObj 缓存 */
  457. typedef CRingCache2<TAgentSocketObj, CONNID, true> TAgentSocketObjPtrPool;
  458. /* 失效 TSocketObj 缓存 */
  459. typedef CRingPool<TAgentSocketObj> TAgentSocketObjPtrList;
  460. /* 失效 TSocketObj 垃圾回收结构链表 */
  461. typedef CCASQueue<TAgentSocketObj> TAgentSocketObjPtrQueue;
  462. /* 有效 TUdpSocketObj 缓存 */
  463. typedef CRingCache2<TUdpSocketObj, CONNID, true> TUdpSocketObjPtrPool;
  464. /* 失效 TUdpSocketObj 缓存 */
  465. typedef CRingPool<TUdpSocketObj> TUdpSocketObjPtrList;
  466. /* 失效 TUdpSocketObj 垃圾回收结构链表 */
  467. typedef CCASQueue<TUdpSocketObj> TUdpSocketObjPtrQueue;
  468. /* HP_SOCKADDR 比较器 */
  469. struct hp_sockaddr_func
  470. {
  471. struct hash
  472. {
  473. size_t operator() (const HP_SOCKADDR* pA) const
  474. {
  475. return pA->Hash();
  476. }
  477. };
  478. struct equal_to
  479. {
  480. bool operator () (const HP_SOCKADDR* pA, const HP_SOCKADDR* pB) const
  481. {
  482. return pA->EqualTo(*pB);
  483. }
  484. };
  485. };
  486. /* 地址-连接 ID 哈希表 */
  487. typedef unordered_map<const HP_SOCKADDR*, CONNID, hp_sockaddr_func::hash, hp_sockaddr_func::equal_to>
  488. TSockAddrMap;
  489. /* 地址-连接 ID 哈希表迭代器 */
  490. typedef TSockAddrMap::iterator TSockAddrMapI;
  491. /* 地址-连接 ID 哈希表 const 迭代器 */
  492. typedef TSockAddrMap::const_iterator TSockAddrMapCI;
  493. /* IClient 组件关闭上下文 */
  494. struct TClientCloseContext
  495. {
  496. BOOL bFireOnClose;
  497. EnSocketOperation enOperation;
  498. int iErrorCode;
  499. BOOL bNotify;
  500. TClientCloseContext(BOOL bFire = TRUE, EnSocketOperation enOp = SO_CLOSE, int iCode = SE_OK, BOOL bNtf = TRUE)
  501. {
  502. Reset(bFire, enOp, iCode, bNtf);
  503. }
  504. void Reset(BOOL bFire = TRUE, EnSocketOperation enOp = SO_CLOSE, int iCode = SE_OK, BOOL bNtf = TRUE)
  505. {
  506. bFireOnClose = bFire;
  507. enOperation = enOp;
  508. iErrorCode = iCode;
  509. bNotify = bNtf;
  510. }
  511. };
  512. /*****************************************************************************************************/
  513. /******************************************** 公共帮助方法 ********************************************/
  514. /*****************************************************************************************************/
  515. /* 默认工作线程前缀 */
  516. #define DEFAULT_WORKER_THREAD_PREFIX "hp-worker-"
  517. /* 设置当前工作线程名称 */
  518. BOOL SetCurrentWorkerThreadName();
  519. /* 设置工作线程默认名称 */
  520. BOOL SetWorkerThreadDefaultName(THR_ID tid);
  521. /* 获取错误描述文本 */
  522. LPCTSTR GetSocketErrorDesc(EnSocketError enCode);
  523. /* 确定地址簇 */
  524. ADDRESS_FAMILY DetermineAddrFamily(LPCTSTR lpszAddress);
  525. /* 地址字符串地址转换为 HP_ADDR */
  526. BOOL GetInAddr(LPCTSTR lpszAddress, HP_ADDR& addr);
  527. /* 地址字符串地址转换为 HP_SOCKADDR */
  528. BOOL GetSockAddr(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr);
  529. /* 检查字符串是否符合 IP 地址格式 */
  530. BOOL IsIPAddress(LPCTSTR lpszAddress, EnIPAddrType* penType = nullptr);
  531. /* 通过主机名获取 IP 地址 */
  532. BOOL GetIPAddress(LPCTSTR lpszHost, LPTSTR lpszIP, int& iIPLenth, EnIPAddrType& enType);
  533. /* 通过主机名获取 HP_SOCKADDR */
  534. BOOL GetSockAddrByHostName(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr);
  535. /* 通过主机名获取 HP_SOCKADDR */
  536. BOOL GetSockAddrByHostNameDirectly(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR &addr);
  537. /* 枚举主机 IP 地址 */
  538. BOOL EnumHostIPAddresses(LPCTSTR lpszHost, EnIPAddrType enType, LPTIPAddr** lpppIPAddr, int& iIPAddrCount);
  539. /* 填充 LPTIPAddr* */
  540. BOOL RetrieveSockAddrIPAddresses(const vector<HP_PSOCKADDR>& vt, LPTIPAddr** lpppIPAddr, int& iIPAddrCount);
  541. /* 释放 LPTIPAddr* */
  542. BOOL FreeHostIPAddresses(LPTIPAddr* lppIPAddr);
  543. /* 把 HP_SOCKADDR 结构转换为地址字符串 */
  544. BOOL sockaddr_IN_2_A(const HP_SOCKADDR& addr, ADDRESS_FAMILY& usFamily, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort);
  545. /* 把地址字符串转换为 HP_SOCKADDR 结构 */
  546. BOOL sockaddr_A_2_IN(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr);
  547. /* 获取 Socket 的本地或远程地址信息 */
  548. BOOL GetSocketAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort, BOOL bLocal = TRUE);
  549. /* 获取 Socket 的本地地址信息 */
  550. BOOL GetSocketLocalAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort);
  551. /* 获取 Socket 的远程地址信息 */
  552. BOOL GetSocketRemoteAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort);
  553. /* 设置组播选项 */
  554. BOOL SetMultiCastSocketOptions(SOCKET sock, const HP_SOCKADDR& bindAddr, const HP_SOCKADDR& castAddr, int iMCTtl, BOOL bMCLoop);
  555. /* 等待连接 */
  556. int WaitForSocketWrite(SOCKET sock, DWORD dwTimeout);
  557. /* 64 位网络字节序转主机字节序 */
  558. ULONGLONG NToH64(ULONGLONG value);
  559. /* 64 位主机字节序转网络字节序 */
  560. ULONGLONG HToN64(ULONGLONG value);
  561. /* 短整型高低字节交换 */
  562. #define ENDIAN_SWAP_16(A) ((USHORT)((((USHORT)(A) & 0xff00) >> 8) | (((USHORT)(A) & 0x00ff) << 8)))
  563. /* 长整型高低字节交换 */
  564. #define ENDIAN_SWAP_32(A) ((((DWORD)(A) & 0xff000000) >> 24) | \
  565. (((DWORD)(A) & 0x00ff0000) >> 8) | \
  566. (((DWORD)(A) & 0x0000ff00) << 8) | \
  567. (((DWORD)(A) & 0x000000ff) << 24) )
  568. /* 检查是否小端字节序 */
  569. BOOL IsLittleEndian();
  570. /* 短整型主机字节序转小端字节序 */
  571. USHORT HToLE16(USHORT value);
  572. /* 短整型主机字节序转大端字节序 */
  573. USHORT HToBE16(USHORT value);
  574. /* 长整型主机字节序转小端字节序 */
  575. DWORD HToLE32(DWORD value);
  576. /* 长整型主机字节序转大端字节序 */
  577. DWORD HToBE32(DWORD value);
  578. HRESULT ReadSmallFile(LPCTSTR lpszFileName, CFile& file, CFileMapping& fmap, DWORD dwMaxFileSize = MAX_SMALL_FILE_SIZE);
  579. HRESULT MakeSmallFilePackage(LPCTSTR lpszFileName, CFile& file, CFileMapping& fmap, WSABUF szBuf[3], const LPWSABUF pHead = nullptr, const LPWSABUF pTail = nullptr);
  580. /************************************************************************
  581. 名称:setsockopt() 帮助方法
  582. 描述:简化常用的 setsockopt() 调用
  583. ************************************************************************/
  584. int SSO_SetSocketOption (SOCKET sock, int level, int name, LPVOID val, int len);
  585. int SSO_GetSocketOption (SOCKET sock, int level, int name, LPVOID val, int* len);
  586. int SSO_IoctlSocket (SOCKET sock, long cmd, PVOID arg);
  587. int SSO_NoBlock (SOCKET sock, BOOL bNoBlock = TRUE);
  588. int SSO_NoDelay (SOCKET sock, BOOL bNoDelay = TRUE);
  589. int SSO_DontLinger (SOCKET sock, BOOL bDont = TRUE);
  590. int SSO_Linger (SOCKET sock, int l_onoff, int l_linger);
  591. int SSO_KeepAlive (SOCKET sock, BOOL bKeepAlive = TRUE);
  592. int SSO_KeepAliveVals (SOCKET sock, BOOL bOnOff, DWORD dwIdle, DWORD dwInterval, DWORD dwCount = 5);
  593. int SSO_ReuseAddress (SOCKET sock, EnReuseAddressPolicy opt);
  594. int SSO_RecvBuffSize (SOCKET sock, int size);
  595. int SSO_SendBuffSize (SOCKET sock, int size);
  596. int SSO_RecvTimeOut (SOCKET sock, int ms);
  597. int SSO_SendTimeOut (SOCKET sock, int ms);
  598. int SSO_GetError (SOCKET sock);
  599. /* 生成 Connection ID */
  600. CONNID GenerateConnectionID();
  601. /* 检测 UDP 连接关闭通知 */
  602. int IsUdpCloseNotify(const BYTE* pData, int iLength);
  603. /* 发送 UDP 连接关闭通知 */
  604. int SendUdpCloseNotify(SOCKET sock);
  605. /* 发送 UDP 连接关闭通知 */
  606. int SendUdpCloseNotify(SOCKET sock, const HP_SOCKADDR& remoteAddr);
  607. /* 关闭 Socket */
  608. int ManualCloseSocket(SOCKET sock, int iShutdownFlag = 0xFF, BOOL bGraceful = TRUE);
  609. #ifdef _ICONV_SUPPORT
  610. #define CHARSET_GBK "GBK"
  611. #define CHARSET_UTF_8 "UTF-8"
  612. #define CHARSET_UTF_16LE "UTF-16LE"
  613. #define CHARSET_UTF_32LE "UTF-32LE"
  614. #define CHARSET_UTF_16BE "UTF-16BE"
  615. #define CHARSET_UTF_32BE "UTF-32BE"
  616. // 系统 UNICODE 字符集
  617. #define SYSTEM_CHARSET_UNICODE ( (sizeof(WCHAR) == 4) \
  618. ? (IsLittleEndian() ? CHARSET_UTF_32LE : CHARSET_UTF_32BE) \
  619. : (IsLittleEndian() ? CHARSET_UTF_16LE : CHARSET_UTF_16BE) )
  620. // Charset A -> Charset B
  621. BOOL CharsetConvert(LPCSTR lpszFromCharset, LPCSTR lpszToCharset, LPCSTR lpszInBuf, int iInBufLen, LPSTR lpszOutBuf, int& iOutBufLen);
  622. // GBK -> UNICODE
  623. BOOL GbkToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength);
  624. // UNICODE -> GBK
  625. BOOL UnicodeToGbkEx(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength);
  626. // UTF8 -> UNICODE
  627. BOOL Utf8ToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength);
  628. // UNICODE -> UTF8
  629. BOOL UnicodeToUtf8Ex(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength);
  630. // GBK -> UTF8
  631. BOOL GbkToUtf8Ex(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength);
  632. // UTF8 -> GBK
  633. BOOL Utf8ToGbkEx(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength);
  634. // GBK -> UNICODE
  635. BOOL GbkToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength);
  636. // UNICODE -> GBK
  637. BOOL UnicodeToGbk(const WCHAR szSrc[], char szDest[], int& iDestLength);
  638. // UTF8 -> UNICODE
  639. BOOL Utf8ToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength);
  640. // UNICODE -> UTF8
  641. BOOL UnicodeToUtf8(const WCHAR szSrc[], char szDest[], int& iDestLength);
  642. // GBK -> UTF8
  643. BOOL GbkToUtf8(const char szSrc[], char szDest[], int& iDestLength);
  644. // UTF8 -> GBK
  645. BOOL Utf8ToGbk(const char szSrc[], char szDest[], int& iDestLength);
  646. #endif
  647. // 计算 Base64 编码后长度
  648. DWORD GuessBase64EncodeBound(DWORD dwSrcLen);
  649. // 计算 Base64 解码后长度
  650. DWORD GuessBase64DecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  651. // Base64 编码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  652. int Base64Encode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  653. // Base64 解码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  654. int Base64Decode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  655. // 计算 URL 编码后长度
  656. DWORD GuessUrlEncodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  657. // 计算 URL 解码后长度
  658. DWORD GuessUrlDecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  659. // URL 编码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  660. int UrlEncode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  661. // URL 解码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  662. int UrlDecode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  663. /* 销毁压缩器对象 */
  664. void DestroyCompressor(IHPCompressor* pCompressor);
  665. /* 销毁解压器对象 */
  666. void DestroyDecompressor(IHPDecompressor* pDecompressor);
  667. #ifdef _ZLIB_SUPPORT
  668. /* ZLib 压缩器 */
  669. class CHPZLibCompressor : public IHPCompressor
  670. {
  671. public:
  672. virtual BOOL Process(const BYTE* pData, int iLength, BOOL bLast, PVOID pContext = nullptr);
  673. virtual BOOL ProcessEx(const BYTE* pData, int iLength, BOOL bLast, BOOL bFlush = FALSE, PVOID pContext = nullptr);
  674. virtual BOOL IsValid() {return m_bValid;}
  675. virtual BOOL Reset();
  676. public:
  677. CHPZLibCompressor(Fn_CompressDataCallback fnCallback, int iWindowBits = MAX_WBITS, int iLevel = Z_DEFAULT_COMPRESSION, int iMethod = Z_DEFLATED, int iMemLevel = MAX_MEM_LEVEL, int iStrategy = Z_DEFAULT_STRATEGY, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  678. virtual ~CHPZLibCompressor();
  679. private:
  680. Fn_CompressDataCallback m_fnCallback;
  681. z_stream m_Stream;
  682. BOOL m_bValid;
  683. DWORD m_dwBuffSize;
  684. };
  685. /* ZLib 解压器 */
  686. class CHPZLibDecompressor : public IHPDecompressor
  687. {
  688. public:
  689. virtual BOOL Process(const BYTE* pData, int iLength, PVOID pContext = nullptr);
  690. virtual BOOL IsValid() {return m_bValid;}
  691. virtual BOOL Reset();
  692. public:
  693. CHPZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits = MAX_WBITS, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  694. virtual ~CHPZLibDecompressor();
  695. private:
  696. Fn_DecompressDataCallback m_fnCallback;
  697. z_stream m_Stream;
  698. BOOL m_bValid;
  699. DWORD m_dwBuffSize;
  700. };
  701. /* 创建 ZLib 压缩器对象 */
  702. IHPCompressor* CreateZLibCompressor(Fn_CompressDataCallback fnCallback, int iWindowBits = MAX_WBITS, int iLevel = Z_DEFAULT_COMPRESSION, int iMethod = Z_DEFLATED, int iMemLevel = MAX_MEM_LEVEL, int iStrategy = Z_DEFAULT_STRATEGY, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  703. /* 创建 GZip 压缩器对象 */
  704. IHPCompressor* CreateGZipCompressor(Fn_CompressDataCallback fnCallback, int iLevel = Z_DEFAULT_COMPRESSION, int iMethod = Z_DEFLATED, int iMemLevel = MAX_MEM_LEVEL, int iStrategy = Z_DEFAULT_STRATEGY, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  705. /* 创建 ZLib 解压器对象 */
  706. IHPDecompressor* CreateZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits = MAX_WBITS, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  707. /* 创建 GZip 解压器对象 */
  708. IHPDecompressor* CreateGZipDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  709. // 普通压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  710. int Compress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  711. // 高级压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  712. int CompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iLevel = Z_DEFAULT_COMPRESSION, int iMethod = Z_DEFLATED, int iWindowBits = MAX_WBITS, int iMemLevel = MAX_MEM_LEVEL, int iStrategy = Z_DEFAULT_STRATEGY);
  713. // 普通解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  714. int Uncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  715. // 高级解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  716. int UncompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iWindowBits = MAX_WBITS);
  717. // 推测压缩结果长度
  718. DWORD GuessCompressBound(DWORD dwSrcLen, BOOL bGZip = FALSE);
  719. // Gzip 压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  720. int GZipCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  721. // Gzip 解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  722. int GZipUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  723. // 推测 Gzip 解压结果长度(如果返回 0 或不合理值则说明输入内容并非有效的 Gzip 格式)
  724. DWORD GZipGuessUncompressBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  725. #endif
  726. #ifdef _BROTLI_SUPPORT
  727. /* Brotli 压缩器 */
  728. class CHPBrotliCompressor : public IHPCompressor
  729. {
  730. public:
  731. virtual BOOL Process(const BYTE* pData, int iLength, BOOL bLast, PVOID pContext = nullptr);
  732. virtual BOOL ProcessEx(const BYTE* pData, int iLength, BOOL bLast, BOOL bFlush = FALSE, PVOID pContext = nullptr);
  733. virtual BOOL IsValid() {return m_bValid;}
  734. virtual BOOL Reset();
  735. public:
  736. CHPBrotliCompressor(Fn_CompressDataCallback fnCallback, int iQuality = BROTLI_DEFAULT_QUALITY, int iWindow = BROTLI_DEFAULT_WINDOW, int iMode = BROTLI_DEFAULT_MODE, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  737. virtual ~CHPBrotliCompressor();
  738. private:
  739. Fn_CompressDataCallback m_fnCallback;
  740. BrotliEncoderState* m_pState;
  741. BOOL m_bValid;
  742. int m_iQuality;
  743. int m_iWindow;
  744. int m_iMode;
  745. DWORD m_dwBuffSize;
  746. };
  747. /* Brotli 解压器 */
  748. class CHPBrotliDecompressor : public IHPDecompressor
  749. {
  750. public:
  751. virtual BOOL Process(const BYTE* pData, int iLength, PVOID pContext = nullptr);
  752. virtual BOOL IsValid() {return m_bValid;}
  753. virtual BOOL Reset();
  754. public:
  755. CHPBrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  756. virtual ~CHPBrotliDecompressor();
  757. private:
  758. Fn_DecompressDataCallback m_fnCallback;
  759. BrotliDecoderState* m_pState;
  760. BOOL m_bValid;
  761. DWORD m_dwBuffSize;
  762. };
  763. /* 创建 Brotli 压缩器对象 */
  764. IHPCompressor* CreateBrotliCompressor(Fn_CompressDataCallback fnCallback, int iQuality = BROTLI_DEFAULT_QUALITY, int iWindow = BROTLI_DEFAULT_WINDOW, int iMode = BROTLI_DEFAULT_MODE, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  765. /* 创建 Brotli 解压器对象 */
  766. IHPDecompressor* CreateBrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  767. // Brotli 压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  768. int BrotliCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  769. // Brotli 高级压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  770. int BrotliCompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iQuality = BROTLI_DEFAULT_QUALITY, int iWindow = BROTLI_DEFAULT_WINDOW, int iMode = BROTLI_DEFAULT_MODE);
  771. // Brotli 解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  772. int BrotliUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  773. // Brotli 推测压缩结果长度
  774. DWORD BrotliGuessCompressBound(DWORD dwSrcLen);
  775. #endif