SocketHelper.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008
  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 CCASQueue<TNodeBufferObj> CNodeRecvQueue;
  242. typedef TItemPtrT<TNodeBufferObj> TNodeBufferObjPtr;
  243. typedef CNodePoolT<TNodeBufferObj> CNodeBufferObjPool;
  244. typedef TItemListExT<TNodeBufferObj, volatile int> TNodeBufferObjList;
  245. /* Server 组件和 Agent 组件内部使用的事件处理结果常量 */
  246. // 连接已关闭
  247. #define HR_CLOSED 0xFF
  248. /* 命令类型 */
  249. enum EnDispCmdType
  250. {
  251. DISP_CMD_SEND = 0x01, // 发送数据
  252. DISP_CMD_RECEIVE = 0x02, // 接收数据
  253. DISP_CMD_UNPAUSE = 0x03, // 恢复接收数据
  254. DISP_CMD_DISCONNECT = 0x04, // 断开连接
  255. DISP_CMD_TIMEOUT = 0x05 // 保活超时
  256. };
  257. /* 关闭连接标识 */
  258. enum EnSocketCloseFlag
  259. {
  260. SCF_NONE = 0, // 不触发事件
  261. SCF_CLOSE = 1, // 触发 正常关闭 OnClose 事件
  262. SCF_ERROR = 2 // 触发 异常关闭 OnClose 事件
  263. };
  264. /* 数据缓冲节点 */
  265. typedef TItem TBufferObj;
  266. /* 数据缓冲节点智能指针 */
  267. typedef TItemPtr TBufferObjPtr;
  268. /* 数据缓冲区对象池 */
  269. typedef CItemPool CBufferObjPool;
  270. /* 数据缓冲区链表模板 */
  271. typedef TItemListExV TBufferObjList;
  272. /* 线程 ID - 接收缓冲区哈希表 */
  273. typedef unordered_map<THR_ID, CBufferPtr*> TReceiveBufferMap;
  274. /* 线程 ID - 接收缓冲区哈希表迭代器 */
  275. typedef TReceiveBufferMap::iterator TReceiveBufferMapI;
  276. /* 线程 ID - 接收缓冲区哈希表 const 迭代器 */
  277. typedef TReceiveBufferMap::const_iterator TReceiveBufferMapCI;
  278. /* Socket 缓冲区基础结构 */
  279. struct TSocketObjBase : public CSafeCounter
  280. {
  281. CPrivateHeap& heap;
  282. CONNID connID;
  283. HP_SOCKADDR remoteAddr;
  284. PVOID extra;
  285. PVOID reserved;
  286. PVOID reserved2;
  287. DWORD activeTime;
  288. union
  289. {
  290. DWORD freeTime;
  291. DWORD connTime;
  292. };
  293. volatile BOOL valid;
  294. volatile BOOL connected;
  295. volatile BOOL paused;
  296. TSocketObjBase(CPrivateHeap& hp) : heap(hp) {}
  297. static BOOL IsExist(TSocketObjBase* pSocketObj)
  298. {return pSocketObj != nullptr;}
  299. static BOOL IsValid(TSocketObjBase* pSocketObj)
  300. {return (IsExist(pSocketObj) && pSocketObj->valid == TRUE);}
  301. static void Invalid(TSocketObjBase* pSocketObj)
  302. {ASSERT(IsExist(pSocketObj)); pSocketObj->valid = FALSE;}
  303. static void Release(TSocketObjBase* pSocketObj)
  304. {ASSERT(IsExist(pSocketObj)); pSocketObj->freeTime = ::TimeGetTime();}
  305. DWORD GetConnTime () const {return connTime;}
  306. DWORD GetFreeTime () const {return freeTime;}
  307. DWORD GetActiveTime () const {return activeTime;}
  308. BOOL IsPaused () const {return paused;}
  309. BOOL HasConnected() {return connected == TRUE;}
  310. BOOL IsConnecting() {return connected == CST_CONNECTING;}
  311. void SetConnected(BOOL bConnected = TRUE) {connected = bConnected;}
  312. void Reset(CONNID dwConnID)
  313. {
  314. ResetCount();
  315. connID = dwConnID;
  316. connected = FALSE;
  317. valid = TRUE;
  318. paused = FALSE;
  319. extra = nullptr;
  320. reserved = nullptr;
  321. reserved2 = nullptr;
  322. }
  323. };
  324. /* 数据缓冲区结构 */
  325. struct TSocketObj : public TSocketObjBase
  326. {
  327. using __super = TSocketObjBase;
  328. CReentrantCriSec csIo;
  329. CReentrantCriSec csSend;
  330. SOCKET socket;
  331. TBufferObjList sndBuff;
  332. static TSocketObj* Construct(CPrivateHeap& hp, CBufferObjPool& bfPool)
  333. {
  334. TSocketObj* pSocketObj = (TSocketObj*)hp.Alloc(sizeof(TSocketObj));
  335. ASSERT(pSocketObj);
  336. return new (pSocketObj) TSocketObj(hp, bfPool);
  337. }
  338. static void Destruct(TSocketObj* pSocketObj)
  339. {
  340. ASSERT(pSocketObj);
  341. CPrivateHeap& heap = pSocketObj->heap;
  342. pSocketObj->TSocketObj::~TSocketObj();
  343. heap.Free(pSocketObj);
  344. }
  345. TSocketObj(CPrivateHeap& hp, CBufferObjPool& bfPool)
  346. : __super(hp), sndBuff(bfPool)
  347. {
  348. }
  349. static void Release(TSocketObj* pSocketObj)
  350. {
  351. __super::Release(pSocketObj);
  352. pSocketObj->sndBuff.Release();
  353. }
  354. int Pending() {return sndBuff.Length();}
  355. BOOL IsPending() {return Pending() > 0;}
  356. static BOOL InvalidSocketObj(TSocketObj* pSocketObj)
  357. {
  358. BOOL bDone = FALSE;
  359. if(TSocketObjBase::IsValid(pSocketObj))
  360. {
  361. pSocketObj->SetConnected(FALSE);
  362. CReentrantCriSecLock locallock(pSocketObj->csIo);
  363. CReentrantCriSecLock locallock2(pSocketObj->csSend);
  364. if(TSocketObjBase::IsValid(pSocketObj))
  365. {
  366. TSocketObjBase::Invalid(pSocketObj);
  367. bDone = TRUE;
  368. }
  369. }
  370. return bDone;
  371. }
  372. void Reset(CONNID dwConnID, SOCKET soClient)
  373. {
  374. __super::Reset(dwConnID);
  375. socket = soClient;
  376. }
  377. };
  378. /* Agent 数据缓冲区结构 */
  379. struct TAgentSocketObj : public TSocketObj
  380. {
  381. using __super = TSocketObj;
  382. CStringA host;
  383. static TAgentSocketObj* Construct(CPrivateHeap& hp, CBufferObjPool& bfPool)
  384. {
  385. TAgentSocketObj* pSocketObj = (TAgentSocketObj*)hp.Alloc(sizeof(TAgentSocketObj));
  386. ASSERT(pSocketObj);
  387. return new (pSocketObj) TAgentSocketObj(hp, bfPool);
  388. }
  389. static void Destruct(TAgentSocketObj* pSocketObj)
  390. {
  391. ASSERT(pSocketObj);
  392. CPrivateHeap& heap = pSocketObj->heap;
  393. pSocketObj->TAgentSocketObj::~TAgentSocketObj();
  394. heap.Free(pSocketObj);
  395. }
  396. TAgentSocketObj(CPrivateHeap& hp, CBufferObjPool& bfPool)
  397. : __super(hp, bfPool)
  398. {
  399. }
  400. void Reset(CONNID dwConnID, SOCKET soClient)
  401. {
  402. __super::Reset(dwConnID, soClient);
  403. host.Empty();
  404. }
  405. BOOL GetRemoteHost(LPCSTR* lpszHost, USHORT* pusPort = nullptr)
  406. {
  407. *lpszHost = host;
  408. if(pusPort)
  409. *pusPort = remoteAddr.Port();
  410. return (!host.IsEmpty());
  411. }
  412. };
  413. /* UDP 数据缓冲区结构 */
  414. struct TUdpSocketObj : public TSocketObjBase
  415. {
  416. using __super = TSocketObjBase;
  417. using CRecvQueue = CCASQueue<TItem>;
  418. PVOID pHolder;
  419. FD fdTimer;
  420. CBufferObjPool& itPool;
  421. CRWLock lcIo;
  422. CRWLock lcSend;
  423. CCriSec csSend;
  424. TBufferObjList sndBuff;
  425. CRecvQueue recvQueue;
  426. volatile DWORD detectFails;
  427. static TUdpSocketObj* Construct(CPrivateHeap& hp, CBufferObjPool& bfPool)
  428. {
  429. TUdpSocketObj* pSocketObj = (TUdpSocketObj*)hp.Alloc(sizeof(TUdpSocketObj));
  430. ASSERT(pSocketObj);
  431. return new (pSocketObj) TUdpSocketObj(hp, bfPool);
  432. }
  433. static void Destruct(TUdpSocketObj* pSocketObj)
  434. {
  435. ASSERT(pSocketObj);
  436. CPrivateHeap& heap = pSocketObj->heap;
  437. pSocketObj->TUdpSocketObj::~TUdpSocketObj();
  438. heap.Free(pSocketObj);
  439. }
  440. TUdpSocketObj(CPrivateHeap& hp, CBufferObjPool& bfPool)
  441. : __super(hp), sndBuff(bfPool), itPool(bfPool)
  442. {
  443. }
  444. ~TUdpSocketObj()
  445. {
  446. ClearRecvQueue();
  447. }
  448. static void Release(TUdpSocketObj* pSocketObj)
  449. {
  450. __super::Release(pSocketObj);
  451. pSocketObj->ClearRecvQueue();
  452. pSocketObj->sndBuff.Release();
  453. }
  454. int Pending() {return sndBuff.Length();}
  455. BOOL IsPending() {return Pending() > 0;}
  456. BOOL HasRecvData() {return !recvQueue.IsEmpty();}
  457. static BOOL InvalidSocketObj(TUdpSocketObj* pSocketObj)
  458. {
  459. BOOL bDone = FALSE;
  460. if(TSocketObjBase::IsValid(pSocketObj))
  461. {
  462. pSocketObj->SetConnected(FALSE);
  463. CReentrantWriteLock locallock(pSocketObj->lcIo);
  464. CReentrantWriteLock locallock2(pSocketObj->lcSend);
  465. CCriSecLock locallock3(pSocketObj->csSend);
  466. if(TSocketObjBase::IsValid(pSocketObj))
  467. {
  468. TSocketObjBase::Invalid(pSocketObj);
  469. bDone = TRUE;
  470. }
  471. }
  472. return bDone;
  473. }
  474. void Reset(CONNID dwConnID)
  475. {
  476. __super::Reset(dwConnID);
  477. pHolder = nullptr;
  478. fdTimer = INVALID_FD;
  479. detectFails = 0;
  480. }
  481. void ClearRecvQueue()
  482. {
  483. TItem* pItem = nullptr;
  484. while(recvQueue.PopFront(&pItem))
  485. itPool.PutFreeItem(pItem);
  486. VERIFY(recvQueue.IsEmpty());
  487. }
  488. };
  489. /* 有效 TSocketObj 缓存 */
  490. typedef CRingCache2<TSocketObj, CONNID, true> TSocketObjPtrPool;
  491. /* 失效 TSocketObj 缓存 */
  492. typedef CRingPool<TSocketObj> TSocketObjPtrList;
  493. /* 失效 TSocketObj 垃圾回收结构链表 */
  494. typedef CCASQueue<TSocketObj> TSocketObjPtrQueue;
  495. /* 有效 TSocketObj 缓存 */
  496. typedef CRingCache2<TAgentSocketObj, CONNID, true> TAgentSocketObjPtrPool;
  497. /* 失效 TSocketObj 缓存 */
  498. typedef CRingPool<TAgentSocketObj> TAgentSocketObjPtrList;
  499. /* 失效 TSocketObj 垃圾回收结构链表 */
  500. typedef CCASQueue<TAgentSocketObj> TAgentSocketObjPtrQueue;
  501. /* 有效 TUdpSocketObj 缓存 */
  502. typedef CRingCache2<TUdpSocketObj, CONNID, true> TUdpSocketObjPtrPool;
  503. /* 失效 TUdpSocketObj 缓存 */
  504. typedef CRingPool<TUdpSocketObj> TUdpSocketObjPtrList;
  505. /* 失效 TUdpSocketObj 垃圾回收结构链表 */
  506. typedef CCASQueue<TUdpSocketObj> TUdpSocketObjPtrQueue;
  507. /* HP_SOCKADDR 比较器 */
  508. struct hp_sockaddr_func
  509. {
  510. struct hash
  511. {
  512. size_t operator() (const HP_SOCKADDR* pA) const
  513. {
  514. return pA->Hash();
  515. }
  516. };
  517. struct equal_to
  518. {
  519. bool operator () (const HP_SOCKADDR* pA, const HP_SOCKADDR* pB) const
  520. {
  521. return pA->EqualTo(*pB);
  522. }
  523. };
  524. };
  525. /* 地址-连接 ID 哈希表 */
  526. typedef unordered_map<const HP_SOCKADDR*, CONNID, hp_sockaddr_func::hash, hp_sockaddr_func::equal_to>
  527. TSockAddrMap;
  528. /* 地址-连接 ID 哈希表迭代器 */
  529. typedef TSockAddrMap::iterator TSockAddrMapI;
  530. /* 地址-连接 ID 哈希表 const 迭代器 */
  531. typedef TSockAddrMap::const_iterator TSockAddrMapCI;
  532. /* IClient 组件关闭上下文 */
  533. struct TClientCloseContext
  534. {
  535. BOOL bFireOnClose;
  536. EnSocketOperation enOperation;
  537. int iErrorCode;
  538. BOOL bNotify;
  539. TClientCloseContext(BOOL bFire = TRUE, EnSocketOperation enOp = SO_CLOSE, int iCode = SE_OK, BOOL bNtf = TRUE)
  540. {
  541. Reset(bFire, enOp, iCode, bNtf);
  542. }
  543. void Reset(BOOL bFire = TRUE, EnSocketOperation enOp = SO_CLOSE, int iCode = SE_OK, BOOL bNtf = TRUE)
  544. {
  545. bFireOnClose = bFire;
  546. enOperation = enOp;
  547. iErrorCode = iCode;
  548. bNotify = bNtf;
  549. }
  550. };
  551. /*****************************************************************************************************/
  552. /******************************************** 公共帮助方法 ********************************************/
  553. /*****************************************************************************************************/
  554. /* 默认工作线程前缀 */
  555. #define DEFAULT_WORKER_THREAD_PREFIX "hp-worker-"
  556. /* 设置当前工作线程名称 */
  557. BOOL SetCurrentWorkerThreadName();
  558. /* 设置工作线程默认名称 */
  559. BOOL SetWorkerThreadDefaultName(THR_ID tid);
  560. /* 获取错误描述文本 */
  561. LPCTSTR GetSocketErrorDesc(EnSocketError enCode);
  562. /* 确定地址簇 */
  563. ADDRESS_FAMILY DetermineAddrFamily(LPCTSTR lpszAddress);
  564. /* 地址字符串地址转换为 HP_ADDR */
  565. BOOL GetInAddr(LPCTSTR lpszAddress, HP_ADDR& addr);
  566. /* 地址字符串地址转换为 HP_SOCKADDR */
  567. BOOL GetSockAddr(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr);
  568. /* 检查字符串是否符合 IP 地址格式 */
  569. BOOL IsIPAddress(LPCTSTR lpszAddress, EnIPAddrType* penType = nullptr);
  570. /* 通过主机名获取 IP 地址 */
  571. BOOL GetIPAddress(LPCTSTR lpszHost, LPTSTR lpszIP, int& iIPLenth, EnIPAddrType& enType);
  572. /* 通过主机名获取 HP_SOCKADDR */
  573. BOOL GetSockAddrByHostName(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr);
  574. /* 通过主机名获取 HP_SOCKADDR */
  575. BOOL GetSockAddrByHostNameDirectly(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR &addr);
  576. /* 枚举主机 IP 地址 */
  577. BOOL EnumHostIPAddresses(LPCTSTR lpszHost, EnIPAddrType enType, LPTIPAddr** lpppIPAddr, int& iIPAddrCount);
  578. /* 填充 LPTIPAddr* */
  579. BOOL RetrieveSockAddrIPAddresses(const vector<HP_PSOCKADDR>& vt, LPTIPAddr** lpppIPAddr, int& iIPAddrCount);
  580. /* 释放 LPTIPAddr* */
  581. BOOL FreeHostIPAddresses(LPTIPAddr* lppIPAddr);
  582. /* 把 HP_SOCKADDR 结构转换为地址字符串 */
  583. BOOL sockaddr_IN_2_A(const HP_SOCKADDR& addr, ADDRESS_FAMILY& usFamily, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort);
  584. /* 把地址字符串转换为 HP_SOCKADDR 结构 */
  585. BOOL sockaddr_A_2_IN(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr);
  586. /* 获取 Socket 的本地或远程地址信息 */
  587. BOOL GetSocketAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort, BOOL bLocal = TRUE);
  588. /* 获取 Socket 的本地地址信息 */
  589. BOOL GetSocketLocalAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort);
  590. /* 获取 Socket 的远程地址信息 */
  591. BOOL GetSocketRemoteAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort);
  592. /* 设置组播选项 */
  593. BOOL SetMultiCastSocketOptions(SOCKET sock, const HP_SOCKADDR& bindAddr, const HP_SOCKADDR& castAddr, int iMCTtl, BOOL bMCLoop);
  594. /* 64 位网络字节序转主机字节序 */
  595. ULONGLONG NToH64(ULONGLONG value);
  596. /* 64 位主机字节序转网络字节序 */
  597. ULONGLONG HToN64(ULONGLONG value);
  598. /* 短整型高低字节交换 */
  599. #define ENDIAN_SWAP_16(A) ((USHORT)((((USHORT)(A) & 0xff00) >> 8) | (((USHORT)(A) & 0x00ff) << 8)))
  600. /* 长整型高低字节交换 */
  601. #define ENDIAN_SWAP_32(A) ((((DWORD)(A) & 0xff000000) >> 24) | \
  602. (((DWORD)(A) & 0x00ff0000) >> 8) | \
  603. (((DWORD)(A) & 0x0000ff00) << 8) | \
  604. (((DWORD)(A) & 0x000000ff) << 24) )
  605. /* 检查是否小端字节序 */
  606. BOOL IsLittleEndian();
  607. /* 短整型主机字节序转小端字节序 */
  608. USHORT HToLE16(USHORT value);
  609. /* 短整型主机字节序转大端字节序 */
  610. USHORT HToBE16(USHORT value);
  611. /* 长整型主机字节序转小端字节序 */
  612. DWORD HToLE32(DWORD value);
  613. /* 长整型主机字节序转大端字节序 */
  614. DWORD HToBE32(DWORD value);
  615. HRESULT ReadSmallFile(LPCTSTR lpszFileName, CFile& file, CFileMapping& fmap, DWORD dwMaxFileSize = MAX_SMALL_FILE_SIZE);
  616. HRESULT MakeSmallFilePackage(LPCTSTR lpszFileName, CFile& file, CFileMapping& fmap, WSABUF szBuf[3], const LPWSABUF pHead = nullptr, const LPWSABUF pTail = nullptr);
  617. /************************************************************************
  618. 名称:setsockopt() 帮助方法
  619. 描述:简化常用的 setsockopt() 调用
  620. ************************************************************************/
  621. int SSO_SetSocketOption (SOCKET sock, int level, int name, LPVOID val, int len);
  622. int SSO_GetSocketOption (SOCKET sock, int level, int name, LPVOID val, int* len);
  623. int SSO_IoctlSocket (SOCKET sock, long cmd, PVOID arg);
  624. int SSO_NoBlock (SOCKET sock, BOOL bNoBlock = TRUE);
  625. int SSO_NoDelay (SOCKET sock, BOOL bNoDelay = TRUE);
  626. int SSO_DontLinger (SOCKET sock, BOOL bDont = TRUE);
  627. int SSO_Linger (SOCKET sock, int l_onoff, int l_linger);
  628. int SSO_KeepAlive (SOCKET sock, BOOL bKeepAlive = TRUE);
  629. int SSO_KeepAliveVals (SOCKET sock, BOOL bOnOff, DWORD dwIdle, DWORD dwInterval, DWORD dwCount = 5);
  630. int SSO_ReuseAddress (SOCKET sock, EnReuseAddressPolicy opt);
  631. int SSO_RecvBuffSize (SOCKET sock, int size);
  632. int SSO_SendBuffSize (SOCKET sock, int size);
  633. int SSO_RecvTimeOut (SOCKET sock, int ms);
  634. int SSO_SendTimeOut (SOCKET sock, int ms);
  635. int SSO_GetError (SOCKET sock);
  636. /* 生成 Connection ID */
  637. CONNID GenerateConnectionID();
  638. /* 检测 UDP 连接关闭通知 */
  639. int IsUdpCloseNotify(const BYTE* pData, int iLength);
  640. /* 发送 UDP 连接关闭通知 */
  641. int SendUdpCloseNotify(SOCKET sock);
  642. /* 发送 UDP 连接关闭通知 */
  643. int SendUdpCloseNotify(SOCKET sock, const HP_SOCKADDR& remoteAddr);
  644. /* 关闭 Socket */
  645. int ManualCloseSocket(SOCKET sock, int iShutdownFlag = 0xFF, BOOL bGraceful = TRUE);
  646. #ifdef _ICONV_SUPPORT
  647. #define CHARSET_GBK "GBK"
  648. #define CHARSET_UTF_8 "UTF-8"
  649. #define CHARSET_UTF_16LE "UTF-16LE"
  650. #define CHARSET_UTF_32LE "UTF-32LE"
  651. #define CHARSET_UTF_16BE "UTF-16BE"
  652. #define CHARSET_UTF_32BE "UTF-32BE"
  653. // 系统 UNICODE 字符集
  654. #define SYSTEM_CHARSET_UNICODE ( (sizeof(WCHAR) == 4) \
  655. ? (IsLittleEndian() ? CHARSET_UTF_32LE : CHARSET_UTF_32BE) \
  656. : (IsLittleEndian() ? CHARSET_UTF_16LE : CHARSET_UTF_16BE) )
  657. // Charset A -> Charset B
  658. BOOL CharsetConvert(LPCSTR lpszFromCharset, LPCSTR lpszToCharset, LPCSTR lpszInBuf, int iInBufLen, LPSTR lpszOutBuf, int& iOutBufLen);
  659. // GBK -> UNICODE
  660. BOOL GbkToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength);
  661. // UNICODE -> GBK
  662. BOOL UnicodeToGbkEx(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength);
  663. // UTF8 -> UNICODE
  664. BOOL Utf8ToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength);
  665. // UNICODE -> UTF8
  666. BOOL UnicodeToUtf8Ex(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength);
  667. // GBK -> UTF8
  668. BOOL GbkToUtf8Ex(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength);
  669. // UTF8 -> GBK
  670. BOOL Utf8ToGbkEx(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength);
  671. // GBK -> UNICODE
  672. BOOL GbkToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength);
  673. // UNICODE -> GBK
  674. BOOL UnicodeToGbk(const WCHAR szSrc[], char szDest[], int& iDestLength);
  675. // UTF8 -> UNICODE
  676. BOOL Utf8ToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength);
  677. // UNICODE -> UTF8
  678. BOOL UnicodeToUtf8(const WCHAR szSrc[], char szDest[], int& iDestLength);
  679. // GBK -> UTF8
  680. BOOL GbkToUtf8(const char szSrc[], char szDest[], int& iDestLength);
  681. // UTF8 -> GBK
  682. BOOL Utf8ToGbk(const char szSrc[], char szDest[], int& iDestLength);
  683. #endif
  684. // 计算 Base64 编码后长度
  685. DWORD GuessBase64EncodeBound(DWORD dwSrcLen);
  686. // 计算 Base64 解码后长度
  687. DWORD GuessBase64DecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  688. // Base64 编码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  689. int Base64Encode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  690. // Base64 解码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  691. int Base64Decode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  692. // 计算 URL 编码后长度
  693. DWORD GuessUrlEncodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  694. // 计算 URL 解码后长度
  695. DWORD GuessUrlDecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  696. // URL 编码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  697. int UrlEncode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  698. // URL 解码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  699. int UrlDecode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  700. /* 销毁压缩器对象 */
  701. void DestroyCompressor(IHPCompressor* pCompressor);
  702. /* 销毁解压器对象 */
  703. void DestroyDecompressor(IHPDecompressor* pDecompressor);
  704. #ifdef _ZLIB_SUPPORT
  705. /* ZLib 压缩器 */
  706. class CHPZLibCompressor : public IHPCompressor
  707. {
  708. public:
  709. virtual BOOL Process(const BYTE* pData, int iLength, BOOL bLast, PVOID pContext = nullptr);
  710. virtual BOOL ProcessEx(const BYTE* pData, int iLength, BOOL bLast, BOOL bFlush = FALSE, PVOID pContext = nullptr);
  711. virtual BOOL IsValid() {return m_bValid;}
  712. virtual BOOL Reset();
  713. public:
  714. 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);
  715. virtual ~CHPZLibCompressor();
  716. private:
  717. Fn_CompressDataCallback m_fnCallback;
  718. z_stream m_Stream;
  719. BOOL m_bValid;
  720. DWORD m_dwBuffSize;
  721. };
  722. /* ZLib 解压器 */
  723. class CHPZLibDecompressor : public IHPDecompressor
  724. {
  725. public:
  726. virtual BOOL Process(const BYTE* pData, int iLength, PVOID pContext = nullptr);
  727. virtual BOOL IsValid() {return m_bValid;}
  728. virtual BOOL Reset();
  729. public:
  730. CHPZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits = MAX_WBITS, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  731. virtual ~CHPZLibDecompressor();
  732. private:
  733. Fn_DecompressDataCallback m_fnCallback;
  734. z_stream m_Stream;
  735. BOOL m_bValid;
  736. DWORD m_dwBuffSize;
  737. };
  738. /* 创建 ZLib 压缩器对象 */
  739. 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);
  740. /* 创建 GZip 压缩器对象 */
  741. 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);
  742. /* 创建 ZLib 解压器对象 */
  743. IHPDecompressor* CreateZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits = MAX_WBITS, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  744. /* 创建 GZip 解压器对象 */
  745. IHPDecompressor* CreateGZipDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  746. // 普通压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  747. int Compress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  748. // 高级压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  749. 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);
  750. // 普通解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  751. int Uncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  752. // 高级解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  753. int UncompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iWindowBits = MAX_WBITS);
  754. // 推测压缩结果长度
  755. DWORD GuessCompressBound(DWORD dwSrcLen, BOOL bGZip = FALSE);
  756. // Gzip 压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  757. int GZipCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  758. // Gzip 解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  759. int GZipUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  760. // 推测 Gzip 解压结果长度(如果返回 0 或不合理值则说明输入内容并非有效的 Gzip 格式)
  761. DWORD GZipGuessUncompressBound(const BYTE* lpszSrc, DWORD dwSrcLen);
  762. #endif
  763. #ifdef _BROTLI_SUPPORT
  764. /* Brotli 压缩器 */
  765. class CHPBrotliCompressor : public IHPCompressor
  766. {
  767. public:
  768. virtual BOOL Process(const BYTE* pData, int iLength, BOOL bLast, PVOID pContext = nullptr);
  769. virtual BOOL ProcessEx(const BYTE* pData, int iLength, BOOL bLast, BOOL bFlush = FALSE, PVOID pContext = nullptr);
  770. virtual BOOL IsValid() {return m_bValid;}
  771. virtual BOOL Reset();
  772. public:
  773. 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);
  774. virtual ~CHPBrotliCompressor();
  775. private:
  776. Fn_CompressDataCallback m_fnCallback;
  777. BrotliEncoderState* m_pState;
  778. BOOL m_bValid;
  779. int m_iQuality;
  780. int m_iWindow;
  781. int m_iMode;
  782. DWORD m_dwBuffSize;
  783. };
  784. /* Brotli 解压器 */
  785. class CHPBrotliDecompressor : public IHPDecompressor
  786. {
  787. public:
  788. virtual BOOL Process(const BYTE* pData, int iLength, PVOID pContext = nullptr);
  789. virtual BOOL IsValid() {return m_bValid;}
  790. virtual BOOL Reset();
  791. public:
  792. CHPBrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  793. virtual ~CHPBrotliDecompressor();
  794. private:
  795. Fn_DecompressDataCallback m_fnCallback;
  796. BrotliDecoderState* m_pState;
  797. BOOL m_bValid;
  798. DWORD m_dwBuffSize;
  799. };
  800. /* 创建 Brotli 压缩器对象 */
  801. 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);
  802. /* 创建 Brotli 解压器对象 */
  803. IHPDecompressor* CreateBrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
  804. // Brotli 压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  805. int BrotliCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  806. // Brotli 高级压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  807. 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);
  808. // Brotli 解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
  809. int BrotliUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
  810. // Brotli 推测压缩结果长度
  811. DWORD BrotliGuessCompressBound(DWORD dwSrcLen);
  812. #endif