| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008 |
- /*
- * Copyright: JessMA Open Source (ldcsaa@gmail.com)
- *
- * Author : Bruce Liang
- * Website : https://github.com/ldcsaa
- * Project : https://github.com/ldcsaa/HP-Socket
- * Blog : http://www.cnblogs.com/ldcsaa
- * Wiki : http://www.oschina.net/p/hp-socket
- * QQ Group : 44636872, 75375912
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #pragma once
- #include "hpsocket/HPTypeDef.h"
- #include "hpsocket/SocketInterface.h"
- #include "common/StringT.h"
- #include "common/SysHelper.h"
- #include "common/BufferPtr.h"
- #include "common/BufferPool.h"
- #include "common/RingBuffer.h"
- #include "common/FileHelper.h"
- #include "InternalDef.h"
- #include <netdb.h>
- #include <sys/un.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #ifdef _ZLIB_SUPPORT
- #include <zlib.h>
- #endif
- #ifdef _BROTLI_SUPPORT
- #include <brotli/decode.h>
- #include <brotli/encode.h>
- #endif
- using ADDRESS_FAMILY = sa_family_t;
- using IN_ADDR = in_addr;
- using IN6_ADDR = in6_addr;
- using SOCKADDR = sockaddr;
- using SOCKADDR_IN = sockaddr_in;
- using SOCKADDR_IN6 = sockaddr_in6;
- typedef struct hp_addr
- {
- ADDRESS_FAMILY family;
- union
- {
- ULONG_PTR addr;
- IN_ADDR addr4;
- IN6_ADDR addr6;
- };
- static const hp_addr ANY_ADDR4;
- static const hp_addr ANY_ADDR6;
- inline int AddrSize() const
- {
- return AddrSize(family);
- }
- inline static int AddrSize(ADDRESS_FAMILY f)
- {
- if(f == AF_INET)
- return sizeof(IN_ADDR);
- return sizeof(IN6_ADDR);
- }
- inline static const hp_addr& AnyAddr(ADDRESS_FAMILY f)
- {
- if(f == AF_INET)
- return ANY_ADDR4;
- return ANY_ADDR6;
- }
- inline const ULONG_PTR* Addr() const {return &addr;}
- inline ULONG_PTR* Addr() {return &addr;}
- inline BOOL IsIPv4() const {return family == AF_INET;}
- inline BOOL IsIPv6() const {return family == AF_INET6;}
- inline BOOL IsSpecified() const {return IsIPv4() || IsIPv6();}
- inline void ZeroAddr() {::ZeroMemory(&addr6, sizeof(addr6));}
- inline void Reset() {::ZeroMemory(this, sizeof(*this));}
- inline hp_addr& Copy(hp_addr& other) const
- {
- if(this != &other)
- memcpy(&other, this, offsetof(hp_addr, addr) + AddrSize());
- return other;
- }
- hp_addr(ADDRESS_FAMILY f = AF_UNSPEC, BOOL bZeroAddr = FALSE)
- {
- family = f;
- if(bZeroAddr) ZeroAddr();
- }
- } HP_ADDR, *HP_PADDR;
- typedef struct hp_sockaddr
- {
- union
- {
- ADDRESS_FAMILY family;
- SOCKADDR addr;
- SOCKADDR_IN addr4;
- SOCKADDR_IN6 addr6;
- };
- inline int AddrSize() const
- {
- return AddrSize(family);
- }
- inline static int AddrSize(ADDRESS_FAMILY f)
- {
- if(f == AF_INET)
- return sizeof(SOCKADDR_IN);
- return sizeof(SOCKADDR_IN6);
- }
- inline int EffectAddrSize() const
- {
- return EffectAddrSize(family);
- }
- inline static int EffectAddrSize(ADDRESS_FAMILY f)
- {
- return (f == AF_INET) ? offsetof(SOCKADDR_IN, sin_zero) : sizeof(SOCKADDR_IN6);
- }
- inline static const hp_sockaddr& AnyAddr(ADDRESS_FAMILY f)
- {
- static const hp_sockaddr s_any_addr4(AF_INET, TRUE);
- static const hp_sockaddr s_any_addr6(AF_INET6, TRUE);
- if(f == AF_INET)
- return s_any_addr4;
- return s_any_addr6;
- }
- inline static int AddrMinStrLength(ADDRESS_FAMILY f)
- {
- if(f == AF_INET)
- return INET_ADDRSTRLEN;
- return INET6_ADDRSTRLEN;
- }
- inline BOOL IsIPv4() const {return family == AF_INET;}
- inline BOOL IsIPv6() const {return family == AF_INET6;}
- inline BOOL IsSpecified() const {return IsIPv4() || IsIPv6();}
- inline USHORT Port() const {return ntohs(addr4.sin_port);}
- inline void SetPort(USHORT usPort) {addr4.sin_port = htons(usPort);}
- inline void* SinAddr() const {return IsIPv4() ? (void*)&addr4.sin_addr : (void*)&addr6.sin6_addr;}
- inline void* SinAddr() {return IsIPv4() ? (void*)&addr4.sin_addr : (void*)&addr6.sin6_addr;}
- inline const SOCKADDR* Addr() const {return &addr;}
- inline SOCKADDR* Addr() {return &addr;}
- inline void ZeroAddr() {::ZeroMemory(((char*)this) + sizeof(family), sizeof(*this) - sizeof(family));}
- inline void Reset() {::ZeroMemory(this, sizeof(*this));}
- inline hp_sockaddr& Copy(hp_sockaddr& other) const
- {
- if(this != &other)
- memcpy(&other, this, AddrSize());
- return other;
- }
- size_t Hash() const
- {
- ASSERT(IsSpecified());
- size_t _Val = 2166136261U;
- const int size = EffectAddrSize();
- const BYTE* pAddr = (const BYTE*)Addr();
- for(int i = 0; i < size; i++)
- _Val = 16777619U * _Val ^ (size_t)pAddr[i];
- return (_Val);
- }
- bool EqualTo(const hp_sockaddr& other) const
- {
- ASSERT(IsSpecified() && other.IsSpecified());
- return EqualMemory(this, &other, EffectAddrSize());
- }
- hp_sockaddr(ADDRESS_FAMILY f = AF_UNSPEC, BOOL bZeroAddr = FALSE)
- {
- family = f;
- if(bZeroAddr) ZeroAddr();
- }
- } HP_SOCKADDR, *HP_PSOCKADDR;
- typedef struct hp_scope_host
- {
- LPCTSTR addr;
- LPCTSTR name;
- BOOL bNeedFree;
- hp_scope_host(LPCTSTR lpszOriginAddress)
- {
- ASSERT(lpszOriginAddress != nullptr);
- LPCTSTR lpszFind = ::StrChr(lpszOriginAddress, HOST_SEPARATOR_CHAR);
- if(lpszFind == nullptr)
- {
- addr = lpszOriginAddress;
- name = lpszOriginAddress;
- bNeedFree = FALSE;
- }
- else
- {
- int i = (int)(lpszFind - lpszOriginAddress);
- int iSize = (int)lstrlen(lpszOriginAddress) + 1;
- LPTSTR lpszCopy = new TCHAR[iSize];
- ::memcpy((PVOID)lpszCopy, (PVOID)lpszOriginAddress, iSize * sizeof(TCHAR));
- lpszCopy[i] = 0;
- addr = lpszCopy;
- name = lpszCopy + i + 1;
- bNeedFree = TRUE;
- if(::IsStrEmpty(name))
- name = addr;
- }
- }
- ~hp_scope_host()
- {
- if(bNeedFree)
- delete[] addr;
- }
- } HP_SCOPE_HOST, *HP_PSCOPE_HOST;
- struct TNodeBufferObj : public TItem
- {
- using __super = TItem;
- HP_SOCKADDR remoteAddr;
- public:
- void Reset(int first = 0, int last = 0)
- {
- __super::Reset(first, last);
- remoteAddr.Reset();
- }
- public:
- static TNodeBufferObj* Construct(CPrivateHeap& heap,
- int capacity = DEFAULT_ITEM_CAPACITY,
- BYTE* pData = nullptr,
- int length = 0)
- {
- return ::ConstructItemT((TNodeBufferObj*)(nullptr), heap, capacity, pData, length);
- }
- static void Destruct(TNodeBufferObj* pBufferObj)
- {
- ::DestructItemT(pBufferObj);
- }
- TNodeBufferObj(CPrivateHeap& hp, BYTE* pHead, int cap = DEFAULT_ITEM_CAPACITY, BYTE* pData = nullptr, int length = 0)
- : TItem(hp, pHead, cap, pData, length)
- {
- }
- ~TNodeBufferObj()
- {
- }
- DECLARE_NO_COPY_CLASS(TNodeBufferObj)
- };
- typedef CCASQueue<TNodeBufferObj> CNodeRecvQueue;
- typedef TItemPtrT<TNodeBufferObj> TNodeBufferObjPtr;
- typedef CNodePoolT<TNodeBufferObj> CNodeBufferObjPool;
- typedef TItemListExT<TNodeBufferObj, volatile int> TNodeBufferObjList;
- /* Server 组件和 Agent 组件内部使用的事件处理结果常量 */
- // 连接已关闭
- #define HR_CLOSED 0xFF
- /* 命令类型 */
- enum EnDispCmdType
- {
- DISP_CMD_SEND = 0x01, // 发送数据
- DISP_CMD_RECEIVE = 0x02, // 接收数据
- DISP_CMD_UNPAUSE = 0x03, // 恢复接收数据
- DISP_CMD_DISCONNECT = 0x04, // 断开连接
- DISP_CMD_TIMEOUT = 0x05 // 保活超时
- };
- /* 关闭连接标识 */
- enum EnSocketCloseFlag
- {
- SCF_NONE = 0, // 不触发事件
- SCF_CLOSE = 1, // 触发 正常关闭 OnClose 事件
- SCF_ERROR = 2 // 触发 异常关闭 OnClose 事件
- };
- /* 数据缓冲节点 */
- typedef TItem TBufferObj;
- /* 数据缓冲节点智能指针 */
- typedef TItemPtr TBufferObjPtr;
- /* 数据缓冲区对象池 */
- typedef CItemPool CBufferObjPool;
- /* 数据缓冲区链表模板 */
- typedef TItemListExV TBufferObjList;
- /* 线程 ID - 接收缓冲区哈希表 */
- typedef unordered_map<THR_ID, CBufferPtr*> TReceiveBufferMap;
- /* 线程 ID - 接收缓冲区哈希表迭代器 */
- typedef TReceiveBufferMap::iterator TReceiveBufferMapI;
- /* 线程 ID - 接收缓冲区哈希表 const 迭代器 */
- typedef TReceiveBufferMap::const_iterator TReceiveBufferMapCI;
- /* Socket 缓冲区基础结构 */
- struct TSocketObjBase : public CSafeCounter
- {
- CPrivateHeap& heap;
- CONNID connID;
- HP_SOCKADDR remoteAddr;
- PVOID extra;
- PVOID reserved;
- PVOID reserved2;
- DWORD activeTime;
- union
- {
- DWORD freeTime;
- DWORD connTime;
- };
- volatile BOOL valid;
- volatile BOOL connected;
- volatile BOOL paused;
- TSocketObjBase(CPrivateHeap& hp) : heap(hp) {}
- static BOOL IsExist(TSocketObjBase* pSocketObj)
- {return pSocketObj != nullptr;}
- static BOOL IsValid(TSocketObjBase* pSocketObj)
- {return (IsExist(pSocketObj) && pSocketObj->valid == TRUE);}
- static void Invalid(TSocketObjBase* pSocketObj)
- {ASSERT(IsExist(pSocketObj)); pSocketObj->valid = FALSE;}
- static void Release(TSocketObjBase* pSocketObj)
- {ASSERT(IsExist(pSocketObj)); pSocketObj->freeTime = ::TimeGetTime();}
- DWORD GetConnTime () const {return connTime;}
- DWORD GetFreeTime () const {return freeTime;}
- DWORD GetActiveTime () const {return activeTime;}
- BOOL IsPaused () const {return paused;}
- BOOL HasConnected() {return connected == TRUE;}
- BOOL IsConnecting() {return connected == CST_CONNECTING;}
- void SetConnected(BOOL bConnected = TRUE) {connected = bConnected;}
- void Reset(CONNID dwConnID)
- {
- ResetCount();
- connID = dwConnID;
- connected = FALSE;
- valid = TRUE;
- paused = FALSE;
- extra = nullptr;
- reserved = nullptr;
- reserved2 = nullptr;
- }
- };
- /* 数据缓冲区结构 */
- struct TSocketObj : public TSocketObjBase
- {
- using __super = TSocketObjBase;
- CReentrantCriSec csIo;
- CReentrantCriSec csSend;
- SOCKET socket;
- TBufferObjList sndBuff;
- static TSocketObj* Construct(CPrivateHeap& hp, CBufferObjPool& bfPool)
- {
- TSocketObj* pSocketObj = (TSocketObj*)hp.Alloc(sizeof(TSocketObj));
- ASSERT(pSocketObj);
- return new (pSocketObj) TSocketObj(hp, bfPool);
- }
- static void Destruct(TSocketObj* pSocketObj)
- {
- ASSERT(pSocketObj);
- CPrivateHeap& heap = pSocketObj->heap;
- pSocketObj->TSocketObj::~TSocketObj();
- heap.Free(pSocketObj);
- }
-
- TSocketObj(CPrivateHeap& hp, CBufferObjPool& bfPool)
- : __super(hp), sndBuff(bfPool)
- {
- }
- static void Release(TSocketObj* pSocketObj)
- {
- __super::Release(pSocketObj);
- pSocketObj->sndBuff.Release();
- }
- int Pending() {return sndBuff.Length();}
- BOOL IsPending() {return Pending() > 0;}
- static BOOL InvalidSocketObj(TSocketObj* pSocketObj)
- {
- BOOL bDone = FALSE;
- if(TSocketObjBase::IsValid(pSocketObj))
- {
- pSocketObj->SetConnected(FALSE);
- CReentrantCriSecLock locallock(pSocketObj->csIo);
- CReentrantCriSecLock locallock2(pSocketObj->csSend);
- if(TSocketObjBase::IsValid(pSocketObj))
- {
- TSocketObjBase::Invalid(pSocketObj);
- bDone = TRUE;
- }
- }
- return bDone;
- }
- void Reset(CONNID dwConnID, SOCKET soClient)
- {
- __super::Reset(dwConnID);
-
- socket = soClient;
- }
- };
- /* Agent 数据缓冲区结构 */
- struct TAgentSocketObj : public TSocketObj
- {
- using __super = TSocketObj;
- CStringA host;
-
- static TAgentSocketObj* Construct(CPrivateHeap& hp, CBufferObjPool& bfPool)
- {
- TAgentSocketObj* pSocketObj = (TAgentSocketObj*)hp.Alloc(sizeof(TAgentSocketObj));
- ASSERT(pSocketObj);
- return new (pSocketObj) TAgentSocketObj(hp, bfPool);
- }
- static void Destruct(TAgentSocketObj* pSocketObj)
- {
- ASSERT(pSocketObj);
- CPrivateHeap& heap = pSocketObj->heap;
- pSocketObj->TAgentSocketObj::~TAgentSocketObj();
- heap.Free(pSocketObj);
- }
-
- TAgentSocketObj(CPrivateHeap& hp, CBufferObjPool& bfPool)
- : __super(hp, bfPool)
- {
- }
- void Reset(CONNID dwConnID, SOCKET soClient)
- {
- __super::Reset(dwConnID, soClient);
- host.Empty();
- }
- BOOL GetRemoteHost(LPCSTR* lpszHost, USHORT* pusPort = nullptr)
- {
- *lpszHost = host;
- if(pusPort)
- *pusPort = remoteAddr.Port();
- return (!host.IsEmpty());
- }
- };
- /* UDP 数据缓冲区结构 */
- struct TUdpSocketObj : public TSocketObjBase
- {
- using __super = TSocketObjBase;
- using CRecvQueue = CCASQueue<TItem>;
- PVOID pHolder;
- FD fdTimer;
- CBufferObjPool& itPool;
- CRWLock lcIo;
- CRWLock lcSend;
- CCriSec csSend;
- TBufferObjList sndBuff;
- CRecvQueue recvQueue;
- volatile DWORD detectFails;
- static TUdpSocketObj* Construct(CPrivateHeap& hp, CBufferObjPool& bfPool)
- {
- TUdpSocketObj* pSocketObj = (TUdpSocketObj*)hp.Alloc(sizeof(TUdpSocketObj));
- ASSERT(pSocketObj);
- return new (pSocketObj) TUdpSocketObj(hp, bfPool);
- }
- static void Destruct(TUdpSocketObj* pSocketObj)
- {
- ASSERT(pSocketObj);
- CPrivateHeap& heap = pSocketObj->heap;
- pSocketObj->TUdpSocketObj::~TUdpSocketObj();
- heap.Free(pSocketObj);
- }
-
- TUdpSocketObj(CPrivateHeap& hp, CBufferObjPool& bfPool)
- : __super(hp), sndBuff(bfPool), itPool(bfPool)
- {
- }
- ~TUdpSocketObj()
- {
- ClearRecvQueue();
- }
- static void Release(TUdpSocketObj* pSocketObj)
- {
- __super::Release(pSocketObj);
- pSocketObj->ClearRecvQueue();
- pSocketObj->sndBuff.Release();
- }
- int Pending() {return sndBuff.Length();}
- BOOL IsPending() {return Pending() > 0;}
- BOOL HasRecvData() {return !recvQueue.IsEmpty();}
- static BOOL InvalidSocketObj(TUdpSocketObj* pSocketObj)
- {
- BOOL bDone = FALSE;
- if(TSocketObjBase::IsValid(pSocketObj))
- {
- pSocketObj->SetConnected(FALSE);
- CReentrantWriteLock locallock(pSocketObj->lcIo);
- CReentrantWriteLock locallock2(pSocketObj->lcSend);
- CCriSecLock locallock3(pSocketObj->csSend);
- if(TSocketObjBase::IsValid(pSocketObj))
- {
- TSocketObjBase::Invalid(pSocketObj);
- bDone = TRUE;
- }
- }
- return bDone;
- }
- void Reset(CONNID dwConnID)
- {
- __super::Reset(dwConnID);
- pHolder = nullptr;
- fdTimer = INVALID_FD;
- detectFails = 0;
- }
- void ClearRecvQueue()
- {
- TItem* pItem = nullptr;
- while(recvQueue.PopFront(&pItem))
- itPool.PutFreeItem(pItem);
- VERIFY(recvQueue.IsEmpty());
- }
- };
- /* 有效 TSocketObj 缓存 */
- typedef CRingCache2<TSocketObj, CONNID, true> TSocketObjPtrPool;
- /* 失效 TSocketObj 缓存 */
- typedef CRingPool<TSocketObj> TSocketObjPtrList;
- /* 失效 TSocketObj 垃圾回收结构链表 */
- typedef CCASQueue<TSocketObj> TSocketObjPtrQueue;
- /* 有效 TSocketObj 缓存 */
- typedef CRingCache2<TAgentSocketObj, CONNID, true> TAgentSocketObjPtrPool;
- /* 失效 TSocketObj 缓存 */
- typedef CRingPool<TAgentSocketObj> TAgentSocketObjPtrList;
- /* 失效 TSocketObj 垃圾回收结构链表 */
- typedef CCASQueue<TAgentSocketObj> TAgentSocketObjPtrQueue;
- /* 有效 TUdpSocketObj 缓存 */
- typedef CRingCache2<TUdpSocketObj, CONNID, true> TUdpSocketObjPtrPool;
- /* 失效 TUdpSocketObj 缓存 */
- typedef CRingPool<TUdpSocketObj> TUdpSocketObjPtrList;
- /* 失效 TUdpSocketObj 垃圾回收结构链表 */
- typedef CCASQueue<TUdpSocketObj> TUdpSocketObjPtrQueue;
- /* HP_SOCKADDR 比较器 */
- struct hp_sockaddr_func
- {
- struct hash
- {
- size_t operator() (const HP_SOCKADDR* pA) const
- {
- return pA->Hash();
- }
- };
- struct equal_to
- {
- bool operator () (const HP_SOCKADDR* pA, const HP_SOCKADDR* pB) const
- {
- return pA->EqualTo(*pB);
- }
- };
- };
- /* 地址-连接 ID 哈希表 */
- typedef unordered_map<const HP_SOCKADDR*, CONNID, hp_sockaddr_func::hash, hp_sockaddr_func::equal_to>
- TSockAddrMap;
- /* 地址-连接 ID 哈希表迭代器 */
- typedef TSockAddrMap::iterator TSockAddrMapI;
- /* 地址-连接 ID 哈希表 const 迭代器 */
- typedef TSockAddrMap::const_iterator TSockAddrMapCI;
- /* IClient 组件关闭上下文 */
- struct TClientCloseContext
- {
- BOOL bFireOnClose;
- EnSocketOperation enOperation;
- int iErrorCode;
- BOOL bNotify;
- TClientCloseContext(BOOL bFire = TRUE, EnSocketOperation enOp = SO_CLOSE, int iCode = SE_OK, BOOL bNtf = TRUE)
- {
- Reset(bFire, enOp, iCode, bNtf);
- }
- void Reset(BOOL bFire = TRUE, EnSocketOperation enOp = SO_CLOSE, int iCode = SE_OK, BOOL bNtf = TRUE)
- {
- bFireOnClose = bFire;
- enOperation = enOp;
- iErrorCode = iCode;
- bNotify = bNtf;
- }
- };
- /*****************************************************************************************************/
- /******************************************** 公共帮助方法 ********************************************/
- /*****************************************************************************************************/
- /* 默认工作线程前缀 */
- #define DEFAULT_WORKER_THREAD_PREFIX "hp-worker-"
- /* 设置当前工作线程名称 */
- BOOL SetCurrentWorkerThreadName();
- /* 设置工作线程默认名称 */
- BOOL SetWorkerThreadDefaultName(THR_ID tid);
- /* 获取错误描述文本 */
- LPCTSTR GetSocketErrorDesc(EnSocketError enCode);
- /* 确定地址簇 */
- ADDRESS_FAMILY DetermineAddrFamily(LPCTSTR lpszAddress);
- /* 地址字符串地址转换为 HP_ADDR */
- BOOL GetInAddr(LPCTSTR lpszAddress, HP_ADDR& addr);
- /* 地址字符串地址转换为 HP_SOCKADDR */
- BOOL GetSockAddr(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr);
- /* 检查字符串是否符合 IP 地址格式 */
- BOOL IsIPAddress(LPCTSTR lpszAddress, EnIPAddrType* penType = nullptr);
- /* 通过主机名获取 IP 地址 */
- BOOL GetIPAddress(LPCTSTR lpszHost, LPTSTR lpszIP, int& iIPLenth, EnIPAddrType& enType);
- /* 通过主机名获取 HP_SOCKADDR */
- BOOL GetSockAddrByHostName(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr);
- /* 通过主机名获取 HP_SOCKADDR */
- BOOL GetSockAddrByHostNameDirectly(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR &addr);
- /* 枚举主机 IP 地址 */
- BOOL EnumHostIPAddresses(LPCTSTR lpszHost, EnIPAddrType enType, LPTIPAddr** lpppIPAddr, int& iIPAddrCount);
- /* 填充 LPTIPAddr* */
- BOOL RetrieveSockAddrIPAddresses(const vector<HP_PSOCKADDR>& vt, LPTIPAddr** lpppIPAddr, int& iIPAddrCount);
- /* 释放 LPTIPAddr* */
- BOOL FreeHostIPAddresses(LPTIPAddr* lppIPAddr);
- /* 把 HP_SOCKADDR 结构转换为地址字符串 */
- BOOL sockaddr_IN_2_A(const HP_SOCKADDR& addr, ADDRESS_FAMILY& usFamily, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort);
- /* 把地址字符串转换为 HP_SOCKADDR 结构 */
- BOOL sockaddr_A_2_IN(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr);
- /* 获取 Socket 的本地或远程地址信息 */
- BOOL GetSocketAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort, BOOL bLocal = TRUE);
- /* 获取 Socket 的本地地址信息 */
- BOOL GetSocketLocalAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort);
- /* 获取 Socket 的远程地址信息 */
- BOOL GetSocketRemoteAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort);
- /* 设置组播选项 */
- BOOL SetMultiCastSocketOptions(SOCKET sock, const HP_SOCKADDR& bindAddr, const HP_SOCKADDR& castAddr, int iMCTtl, BOOL bMCLoop);
- /* 64 位网络字节序转主机字节序 */
- ULONGLONG NToH64(ULONGLONG value);
- /* 64 位主机字节序转网络字节序 */
- ULONGLONG HToN64(ULONGLONG value);
- /* 短整型高低字节交换 */
- #define ENDIAN_SWAP_16(A) ((USHORT)((((USHORT)(A) & 0xff00) >> 8) | (((USHORT)(A) & 0x00ff) << 8)))
- /* 长整型高低字节交换 */
- #define ENDIAN_SWAP_32(A) ((((DWORD)(A) & 0xff000000) >> 24) | \
- (((DWORD)(A) & 0x00ff0000) >> 8) | \
- (((DWORD)(A) & 0x0000ff00) << 8) | \
- (((DWORD)(A) & 0x000000ff) << 24) )
- /* 检查是否小端字节序 */
- BOOL IsLittleEndian();
- /* 短整型主机字节序转小端字节序 */
- USHORT HToLE16(USHORT value);
- /* 短整型主机字节序转大端字节序 */
- USHORT HToBE16(USHORT value);
- /* 长整型主机字节序转小端字节序 */
- DWORD HToLE32(DWORD value);
- /* 长整型主机字节序转大端字节序 */
- DWORD HToBE32(DWORD value);
- HRESULT ReadSmallFile(LPCTSTR lpszFileName, CFile& file, CFileMapping& fmap, DWORD dwMaxFileSize = MAX_SMALL_FILE_SIZE);
- HRESULT MakeSmallFilePackage(LPCTSTR lpszFileName, CFile& file, CFileMapping& fmap, WSABUF szBuf[3], const LPWSABUF pHead = nullptr, const LPWSABUF pTail = nullptr);
- /************************************************************************
- 名称:setsockopt() 帮助方法
- 描述:简化常用的 setsockopt() 调用
- ************************************************************************/
- int SSO_SetSocketOption (SOCKET sock, int level, int name, LPVOID val, int len);
- int SSO_GetSocketOption (SOCKET sock, int level, int name, LPVOID val, int* len);
- int SSO_IoctlSocket (SOCKET sock, long cmd, PVOID arg);
- int SSO_NoBlock (SOCKET sock, BOOL bNoBlock = TRUE);
- int SSO_NoDelay (SOCKET sock, BOOL bNoDelay = TRUE);
- int SSO_DontLinger (SOCKET sock, BOOL bDont = TRUE);
- int SSO_Linger (SOCKET sock, int l_onoff, int l_linger);
- int SSO_KeepAlive (SOCKET sock, BOOL bKeepAlive = TRUE);
- int SSO_KeepAliveVals (SOCKET sock, BOOL bOnOff, DWORD dwIdle, DWORD dwInterval, DWORD dwCount = 5);
- int SSO_ReuseAddress (SOCKET sock, EnReuseAddressPolicy opt);
- int SSO_RecvBuffSize (SOCKET sock, int size);
- int SSO_SendBuffSize (SOCKET sock, int size);
- int SSO_RecvTimeOut (SOCKET sock, int ms);
- int SSO_SendTimeOut (SOCKET sock, int ms);
- int SSO_GetError (SOCKET sock);
- /* 生成 Connection ID */
- CONNID GenerateConnectionID();
- /* 检测 UDP 连接关闭通知 */
- int IsUdpCloseNotify(const BYTE* pData, int iLength);
- /* 发送 UDP 连接关闭通知 */
- int SendUdpCloseNotify(SOCKET sock);
- /* 发送 UDP 连接关闭通知 */
- int SendUdpCloseNotify(SOCKET sock, const HP_SOCKADDR& remoteAddr);
- /* 关闭 Socket */
- int ManualCloseSocket(SOCKET sock, int iShutdownFlag = 0xFF, BOOL bGraceful = TRUE);
- #ifdef _ICONV_SUPPORT
- #define CHARSET_GBK "GBK"
- #define CHARSET_UTF_8 "UTF-8"
- #define CHARSET_UTF_16LE "UTF-16LE"
- #define CHARSET_UTF_32LE "UTF-32LE"
- #define CHARSET_UTF_16BE "UTF-16BE"
- #define CHARSET_UTF_32BE "UTF-32BE"
- // 系统 UNICODE 字符集
- #define SYSTEM_CHARSET_UNICODE ( (sizeof(WCHAR) == 4) \
- ? (IsLittleEndian() ? CHARSET_UTF_32LE : CHARSET_UTF_32BE) \
- : (IsLittleEndian() ? CHARSET_UTF_16LE : CHARSET_UTF_16BE) )
- // Charset A -> Charset B
- BOOL CharsetConvert(LPCSTR lpszFromCharset, LPCSTR lpszToCharset, LPCSTR lpszInBuf, int iInBufLen, LPSTR lpszOutBuf, int& iOutBufLen);
- // GBK -> UNICODE
- BOOL GbkToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength);
- // UNICODE -> GBK
- BOOL UnicodeToGbkEx(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength);
- // UTF8 -> UNICODE
- BOOL Utf8ToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength);
- // UNICODE -> UTF8
- BOOL UnicodeToUtf8Ex(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength);
- // GBK -> UTF8
- BOOL GbkToUtf8Ex(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength);
- // UTF8 -> GBK
- BOOL Utf8ToGbkEx(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength);
- // GBK -> UNICODE
- BOOL GbkToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength);
- // UNICODE -> GBK
- BOOL UnicodeToGbk(const WCHAR szSrc[], char szDest[], int& iDestLength);
- // UTF8 -> UNICODE
- BOOL Utf8ToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength);
- // UNICODE -> UTF8
- BOOL UnicodeToUtf8(const WCHAR szSrc[], char szDest[], int& iDestLength);
- // GBK -> UTF8
- BOOL GbkToUtf8(const char szSrc[], char szDest[], int& iDestLength);
- // UTF8 -> GBK
- BOOL Utf8ToGbk(const char szSrc[], char szDest[], int& iDestLength);
- #endif
- // 计算 Base64 编码后长度
- DWORD GuessBase64EncodeBound(DWORD dwSrcLen);
- // 计算 Base64 解码后长度
- DWORD GuessBase64DecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
- // Base64 编码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int Base64Encode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
- // Base64 解码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int Base64Decode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
- // 计算 URL 编码后长度
- DWORD GuessUrlEncodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
- // 计算 URL 解码后长度
- DWORD GuessUrlDecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
- // URL 编码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int UrlEncode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
- // URL 解码(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int UrlDecode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
- /* 销毁压缩器对象 */
- void DestroyCompressor(IHPCompressor* pCompressor);
- /* 销毁解压器对象 */
- void DestroyDecompressor(IHPDecompressor* pDecompressor);
- #ifdef _ZLIB_SUPPORT
- /* ZLib 压缩器 */
- class CHPZLibCompressor : public IHPCompressor
- {
- public:
- virtual BOOL Process(const BYTE* pData, int iLength, BOOL bLast, PVOID pContext = nullptr);
- virtual BOOL ProcessEx(const BYTE* pData, int iLength, BOOL bLast, BOOL bFlush = FALSE, PVOID pContext = nullptr);
- virtual BOOL IsValid() {return m_bValid;}
- virtual BOOL Reset();
- public:
- 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);
- virtual ~CHPZLibCompressor();
- private:
- Fn_CompressDataCallback m_fnCallback;
- z_stream m_Stream;
- BOOL m_bValid;
- DWORD m_dwBuffSize;
- };
- /* ZLib 解压器 */
- class CHPZLibDecompressor : public IHPDecompressor
- {
- public:
- virtual BOOL Process(const BYTE* pData, int iLength, PVOID pContext = nullptr);
- virtual BOOL IsValid() {return m_bValid;}
- virtual BOOL Reset();
- public:
- CHPZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits = MAX_WBITS, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
- virtual ~CHPZLibDecompressor();
- private:
- Fn_DecompressDataCallback m_fnCallback;
- z_stream m_Stream;
- BOOL m_bValid;
- DWORD m_dwBuffSize;
- };
- /* 创建 ZLib 压缩器对象 */
- 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);
- /* 创建 GZip 压缩器对象 */
- 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);
- /* 创建 ZLib 解压器对象 */
- IHPDecompressor* CreateZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits = MAX_WBITS, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
- /* 创建 GZip 解压器对象 */
- IHPDecompressor* CreateGZipDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
- // 普通压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int Compress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
- // 高级压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- 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);
- // 普通解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int Uncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
- // 高级解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int UncompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iWindowBits = MAX_WBITS);
- // 推测压缩结果长度
- DWORD GuessCompressBound(DWORD dwSrcLen, BOOL bGZip = FALSE);
- // Gzip 压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int GZipCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
- // Gzip 解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int GZipUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
- // 推测 Gzip 解压结果长度(如果返回 0 或不合理值则说明输入内容并非有效的 Gzip 格式)
- DWORD GZipGuessUncompressBound(const BYTE* lpszSrc, DWORD dwSrcLen);
- #endif
- #ifdef _BROTLI_SUPPORT
- /* Brotli 压缩器 */
- class CHPBrotliCompressor : public IHPCompressor
- {
- public:
- virtual BOOL Process(const BYTE* pData, int iLength, BOOL bLast, PVOID pContext = nullptr);
- virtual BOOL ProcessEx(const BYTE* pData, int iLength, BOOL bLast, BOOL bFlush = FALSE, PVOID pContext = nullptr);
- virtual BOOL IsValid() {return m_bValid;}
- virtual BOOL Reset();
- public:
- 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);
- virtual ~CHPBrotliCompressor();
- private:
- Fn_CompressDataCallback m_fnCallback;
- BrotliEncoderState* m_pState;
- BOOL m_bValid;
- int m_iQuality;
- int m_iWindow;
- int m_iMode;
- DWORD m_dwBuffSize;
- };
- /* Brotli 解压器 */
- class CHPBrotliDecompressor : public IHPDecompressor
- {
- public:
- virtual BOOL Process(const BYTE* pData, int iLength, PVOID pContext = nullptr);
- virtual BOOL IsValid() {return m_bValid;}
- virtual BOOL Reset();
- public:
- CHPBrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
- virtual ~CHPBrotliDecompressor();
- private:
- Fn_DecompressDataCallback m_fnCallback;
- BrotliDecoderState* m_pState;
- BOOL m_bValid;
- DWORD m_dwBuffSize;
- };
- /* 创建 Brotli 压缩器对象 */
- 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);
- /* 创建 Brotli 解压器对象 */
- IHPDecompressor* CreateBrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = DEFAULT_COMPRESS_BUFFER_SIZE);
- // Brotli 压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int BrotliCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
- // Brotli 高级压缩(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- 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);
- // Brotli 解压(返回值:0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
- int BrotliUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
- // Brotli 推测压缩结果长度
- DWORD BrotliGuessCompressBound(DWORD dwSrcLen);
- #endif
|