| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970 |
- /*
- * Copyright: JessMA Open Source (ldcsaa@gmail.com)
- *
- * Author : Bruce Liang
- * Website : http://www.jessma.org
- * Project : https://github.com/ldcsaa
- * Blog : http://www.cnblogs.com/ldcsaa
- * Wiki : http://www.oschina.net/p/hp-socket
- * QQ Group : 75375912, 44636872
- *
- * 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.
- */
-
- #include "stdafx.h"
- #include "../Common/Src/GeneralHelper.h"
- #include "../Common/Src/SysHelper.h"
- #include "SocketHelper.h"
- #include <mstcpip.h>
- #pragma comment(lib, "ws2_32")
- #if !defined(stscanf_s)
- #ifdef _UNICODE
- #define stscanf_s swscanf_s
- #else
- #define stscanf_s sscanf_s
- #endif
- #endif
- const hp_addr hp_addr::ANY_ADDR4(AF_INET, TRUE);
- const hp_addr hp_addr::ANY_ADDR6(AF_INET6, TRUE);
- ///////////////////////////////////////////////////////////////////////////////////////////////////////
- ADDRESS_FAMILY DetermineAddrFamily(LPCTSTR lpszAddress)
- {
- if (!lpszAddress || lpszAddress[0] == 0)
- return AF_UNSPEC;
- if(::StrChr(lpszAddress, IPV6_ADDR_SEPARATOR_CHAR))
- return AF_INET6;
- TCHAR c;
- int arr[4];
- if(stscanf_s(lpszAddress, _T("%d.%d.%d.%d%c"), &arr[0], &arr[1], &arr[2], &arr[3], &c, 1) != 4)
- return AF_UNSPEC;
- for(int i = 0; i < 4; i++)
- {
- if(arr[i] < 0 || arr[i] > 255)
- return AF_UNSPEC;
- }
- return AF_INET;
- }
- BOOL GetInAddr(LPCTSTR lpszAddress, HP_ADDR& addr)
- {
- addr.family = DetermineAddrFamily(lpszAddress);
- if (addr.family == AF_UNSPEC)
- return FALSE;
- #if _WIN32_WINNT >= _WIN32_WINNT_VISTA
- return (::InetPton(addr.family, lpszAddress, addr.Addr()) == TRUE);
- #else
- HP_SOCKADDR sockAddr(addr.family);
- if(!GetSockAddr(lpszAddress, 0, sockAddr))
- return FALSE;
- memcpy(addr.Addr(), sockAddr.SinAddr(), addr.AddrSize());
- return TRUE;
- #endif
- }
- BOOL GetSockAddr(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr)
- {
- if(addr.family != AF_INET && addr.family != AF_INET6)
- {
- ::WSASetLastError(WSAEADDRNOTAVAIL);
- return FALSE;
- }
- int iSize = addr.AddrSize();
- if(::WSAStringToAddress((LPTSTR)lpszAddress, addr.family, nullptr, addr.Addr(), &iSize) != NO_ERROR)
- return FALSE;
- if(usPort != 0)
- addr.SetPort(usPort);
- return TRUE;
- }
- BOOL IsIPAddress(LPCTSTR lpszAddress, EnIPAddrType* penType)
- {
- HP_ADDR addr;
- BOOL isOK = GetInAddr(lpszAddress, addr);
- if(isOK && penType)
- *penType = addr.IsIPv4() ? IPT_IPV4 : IPT_IPV6;
- return isOK;
- }
- BOOL GetIPAddress(LPCTSTR lpszHost, LPTSTR lpszIP, int& iIPLen, EnIPAddrType& enType)
- {
- HP_SOCKADDR addr;
- if(!GetSockAddrByHostName(lpszHost, 0, addr))
- return FALSE;
- enType = addr.IsIPv4() ? IPT_IPV4 : IPT_IPV6;
- USHORT usPort;
- ADDRESS_FAMILY usFamily;
- return sockaddr_IN_2_A(addr, usFamily, lpszIP, iIPLen, usPort);
- }
- BOOL GetSockAddrByHostName(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr)
- {
- addr.family = DetermineAddrFamily(lpszHost);
- if(addr.family != AF_UNSPEC)
- return GetSockAddr(lpszHost, usPort, addr);
- return GetSockAddrByHostNameDirectly(lpszHost, usPort, addr);
- }
- BOOL GetSockAddrByHostNameDirectly(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr)
- {
- addr.ZeroAddr();
- addrinfo* pInfo = nullptr;
- addrinfo hints = {0};
- hints.ai_flags = AI_ALL;
- hints.ai_family = addr.family;
- int rs = ::getaddrinfo(CT2A(lpszHost), nullptr, &hints, &pInfo);
- if(rs != NO_ERROR)
- {
- ::WSASetLastError(rs);
- return FALSE;
- }
- BOOL isOK = FALSE;
- for(addrinfo* pCur = pInfo; pCur != nullptr; pCur = pCur->ai_next)
- {
- if(pCur->ai_family == AF_INET || pCur->ai_family == AF_INET6)
- {
- memcpy(addr.Addr(), pCur->ai_addr, pCur->ai_addrlen);
- isOK = TRUE;
- break;
- }
- }
- ::freeaddrinfo(pInfo);
- if(isOK)
- addr.SetPort(usPort);
- else
- ::WSASetLastError(WSAHOST_NOT_FOUND);
- return isOK;
- }
- BOOL EnumHostIPAddresses(LPCTSTR lpszHost, EnIPAddrType enType, LPTIPAddr** lpppIPAddr, int& iIPAddrCount)
- {
- *lpppIPAddr = nullptr;
- iIPAddrCount = 0;
- ADDRESS_FAMILY usFamily = (enType == IPT_ALL ?
- AF_UNSPEC : (enType == IPT_IPV4 ?
- AF_INET : (enType == IPT_IPV6 ?
- AF_INET6 : 0xFF)));
-
- if(usFamily == 0xFF)
- {
- ::WSASetLastError(WSAEAFNOSUPPORT);
- return FALSE;
- }
- vector<HP_PSOCKADDR> vt;
- ADDRESS_FAMILY usFamily2 = DetermineAddrFamily(lpszHost);
- if(usFamily2 != AF_UNSPEC)
- {
- if(usFamily != AF_UNSPEC && usFamily != usFamily2)
- {
- ::WSASetLastError(WSAHOST_NOT_FOUND);
- return FALSE;
- }
- HP_SOCKADDR addr(usFamily2);
- if(!GetSockAddr(lpszHost, 0, addr))
- return FALSE;
- vt.emplace_back(&addr);
- return RetrieveSockAddrIPAddresses(vt, lpppIPAddr, iIPAddrCount);
- }
- addrinfo* pInfo = nullptr;
- addrinfo hints = {0};
- hints.ai_flags = AI_ALL;
- hints.ai_family = usFamily;
- int rs = ::getaddrinfo(CT2A(lpszHost), nullptr, &hints, &pInfo);
- if(rs != NO_ERROR)
- {
- ::WSASetLastError(rs);
- return FALSE;
- }
- for(addrinfo* pCur = pInfo; pCur != nullptr; pCur = pCur->ai_next)
- {
- if(pCur->ai_family == AF_INET || pCur->ai_family == AF_INET6)
- vt.emplace_back((HP_PSOCKADDR)pCur->ai_addr);
- }
- BOOL isOK = RetrieveSockAddrIPAddresses(vt, lpppIPAddr, iIPAddrCount);
- ::freeaddrinfo(pInfo);
- if(!isOK) ::WSASetLastError(WSAHOST_NOT_FOUND);
- return isOK;
- }
- BOOL RetrieveSockAddrIPAddresses(const vector<HP_PSOCKADDR>& vt, LPTIPAddr** lpppIPAddr, int& iIPAddrCount)
- {
- iIPAddrCount = (int)vt.size();
- if(iIPAddrCount == 0) return FALSE;
- HP_PSOCKADDR pSockAddr;
- ADDRESS_FAMILY usFamily;
- USHORT usPort;
- int iAddrLength;
- LPTSTR lpszAddr;
- LPTIPAddr lpItem;
- (*lpppIPAddr) = new LPTIPAddr[iIPAddrCount + 1];
- (*lpppIPAddr)[iIPAddrCount] = nullptr;
- for(int i = 0; i < iIPAddrCount; i++)
- {
- pSockAddr = vt[i];
- iAddrLength = HP_SOCKADDR::AddrMinStrLength(pSockAddr->family) + 6;
- lpszAddr = new TCHAR[iAddrLength];
- VERIFY(sockaddr_IN_2_A(*vt[i], usFamily, lpszAddr, iAddrLength, usPort));
- lpItem = new TIPAddr;
- lpItem->type = pSockAddr->IsIPv4() ? IPT_IPV4 : IPT_IPV6;
- lpItem->address = lpszAddr;
- (*lpppIPAddr)[i] = lpItem;
- }
- return TRUE;
- }
- BOOL FreeHostIPAddresses(LPTIPAddr* lppIPAddr)
- {
- if(!lppIPAddr) return FALSE;
- LPTIPAddr p;
- LPTIPAddr* lppCur = lppIPAddr;
- while((p = *lppCur++) != nullptr)
- {
- delete[] p->address;
- delete p;
- }
- delete[] lppIPAddr;
- return TRUE;
- }
- BOOL sockaddr_IN_2_A(const HP_SOCKADDR& addr, ADDRESS_FAMILY& usFamily, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
- {
- BOOL isOK = FALSE;
- usFamily = addr.family;
- usPort = addr.Port();
- #if _WIN32_WINNT >= _WIN32_WINNT_VISTA
- if(::InetNtop(addr.family, addr.SinAddr(), lpszAddress, iAddressLen))
- {
- iAddressLen = lstrlen(lpszAddress) + 1;
- isOK = TRUE;
- }
- else
- {
- if(::WSAGetLastError() == ERROR_INVALID_PARAMETER)
- iAddressLen = HP_SOCKADDR::AddrMinStrLength(usFamily);
- }
- #else
- if(::WSAAddressToString((LPSOCKADDR)addr.Addr(), addr.AddrSize(), nullptr, lpszAddress, (LPDWORD)&iAddressLen) == NO_ERROR)
- {
- LPTSTR lpszEnd = nullptr;
- BOOL bIPv6 = addr.IsIPv6();
- BOOL bHasPort = (addr.Port() != 0);
- if(!bIPv6)
- {
- if(bHasPort)
- lpszEnd = ::StrChr(lpszAddress, PORT_SEPARATOR_CHAR);
- }
- else
- {
- if(bHasPort)
- {
- static const TCHAR s_szBrk[] = {IPV6_ADDR_END_CHAR, IPV6_ZONE_INDEX_CHAR, 0};
- ASSERT(lpszAddress[0] == IPV6_ADDR_BEGIN_CHAR);
- lpszEnd = ::StrPBrk(lpszAddress, s_szBrk);
- }
- else
- {
- lpszEnd = ::StrChr(lpszAddress, IPV6_ZONE_INDEX_CHAR);
- }
- }
- ASSERT(!bHasPort || lpszEnd);
- if(lpszEnd)
- {
- lpszEnd[0] = 0;
- iAddressLen = lpszEnd - lpszAddress;
- }
- if(bIPv6 && bHasPort)
- memcpy(lpszAddress, (lpszAddress + 1), iAddressLen * sizeof(TCHAR));
- else
- ++iAddressLen;
- isOK = TRUE;
- }
- #endif
- return isOK;
- }
- BOOL sockaddr_A_2_IN(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr)
- {
- addr.family = DetermineAddrFamily(lpszAddress);
- return GetSockAddr(lpszAddress, usPort, addr);
- }
- BOOL GetSocketAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort, BOOL bLocal)
- {
- HP_SOCKADDR addr;
- int addr_len = addr.AddrSize();
- int result = bLocal ? getsockname(socket, addr.Addr(), &addr_len) : getpeername(socket, addr.Addr(), &addr_len);
- if(result != NO_ERROR)
- return FALSE;
- ADDRESS_FAMILY usFamily;
- return sockaddr_IN_2_A(addr, usFamily, lpszAddress, iAddressLen, usPort);
- }
- BOOL GetSocketLocalAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
- {
- return GetSocketAddress(socket, lpszAddress, iAddressLen, usPort, TRUE);
- }
- BOOL GetSocketRemoteAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
- {
- return GetSocketAddress(socket, lpszAddress, iAddressLen, usPort, FALSE);
- }
- ULONGLONG NToH64(ULONGLONG value)
- {
- return (((ULONGLONG)ntohl((u_long)((value << 32) >> 32))) << 32) | ntohl((u_long)(value >> 32));
- }
- ULONGLONG HToN64(ULONGLONG value)
- {
- return (((ULONGLONG)htonl((u_long)((value << 32) >> 32))) << 32) | htonl((u_long)(value >> 32));
- }
- PVOID GetExtensionFuncPtr(SOCKET sock, GUID guid)
- {
- DWORD dwBytes;
- PVOID pfn = nullptr;
- ::WSAIoctl (
- sock,
- SIO_GET_EXTENSION_FUNCTION_POINTER,
- &guid,
- sizeof(guid),
- &pfn,
- sizeof(pfn),
- &dwBytes,
- nullptr,
- nullptr
- );
- return pfn;
- }
- LPFN_ACCEPTEX Get_AcceptEx_FuncPtr(SOCKET sock)
- {
- GUID guid = WSAID_ACCEPTEX;
- return (LPFN_ACCEPTEX)GetExtensionFuncPtr(sock, guid);
- }
- LPFN_GETACCEPTEXSOCKADDRS Get_GetAcceptExSockaddrs_FuncPtr(SOCKET sock)
- {
- GUID guid = WSAID_GETACCEPTEXSOCKADDRS;
- return (LPFN_GETACCEPTEXSOCKADDRS)GetExtensionFuncPtr(sock, guid);
- }
- LPFN_CONNECTEX Get_ConnectEx_FuncPtr(SOCKET sock)
- {
- GUID guid = WSAID_CONNECTEX;
- return (LPFN_CONNECTEX)GetExtensionFuncPtr(sock, guid);
- }
- LPFN_TRANSMITFILE Get_TransmitFile_FuncPtr(SOCKET sock)
- {
- GUID guid = WSAID_TRANSMITFILE;
- return (LPFN_TRANSMITFILE)GetExtensionFuncPtr(sock, guid);
- }
- LPFN_DISCONNECTEX Get_DisconnectEx_FuncPtr (SOCKET sock)
- {
- GUID guid = WSAID_DISCONNECTEX;
- return (LPFN_DISCONNECTEX)GetExtensionFuncPtr(sock, guid);
- }
- HRESULT ReadSmallFile(LPCTSTR lpszFileName, CAtlFile& file, CAtlFileMapping<>& fmap, DWORD dwMaxFileSize)
- {
- ASSERT(lpszFileName != nullptr);
- HRESULT hr = file.Create(lpszFileName, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING);
- if(SUCCEEDED(hr))
- {
- ULONGLONG ullLen;
- hr = file.GetSize(ullLen);
- if(SUCCEEDED(hr))
- {
- if(ullLen > 0 && ullLen <= dwMaxFileSize)
- hr = fmap.MapFile(file);
- else if(ullLen == 0)
- hr = HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
- else
- hr = HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
- }
- }
- return hr;
- }
- HRESULT MakeSmallFilePackage(LPCTSTR lpszFileName, CAtlFile& file, CAtlFileMapping<>& fmap, WSABUF szBuf[3], const LPWSABUF pHead, const LPWSABUF pTail)
- {
- DWORD dwMaxFileSize = MAX_SMALL_FILE_SIZE - (pHead ? pHead->len : 0) - (pTail ? pTail->len : 0);
- ASSERT(dwMaxFileSize <= MAX_SMALL_FILE_SIZE);
- HRESULT hr = ReadSmallFile(lpszFileName, file, fmap, dwMaxFileSize);
- if(SUCCEEDED(hr))
- {
- szBuf[1].len = (ULONG)fmap.GetMappingSize();
- szBuf[1].buf = fmap;
- if(pHead) memcpy(&szBuf[0], pHead, sizeof(WSABUF));
- else memset(&szBuf[0], 0, sizeof(WSABUF));
- if(pTail) memcpy(&szBuf[2], pTail, sizeof(WSABUF));
- else memset(&szBuf[2], 0, sizeof(WSABUF));
- }
- return hr;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////
- BOOL PostIocpCommand(HANDLE hIOCP, EnIocpCommand enCmd, ULONG_PTR ulParam)
- {
- return ::PostQueuedCompletionStatus(hIOCP, enCmd, ulParam, nullptr);
- }
- BOOL PostIocpExit(HANDLE hIOCP)
- {
- return PostIocpCommand(hIOCP, IOCP_CMD_EXIT, 0);
- }
- BOOL PostIocpAccept(HANDLE hIOCP)
- {
- return PostIocpCommand(hIOCP, IOCP_CMD_ACCEPT, 0);
- }
- BOOL PostIocpDisconnect(HANDLE hIOCP, CONNID dwConnID)
- {
- return PostIocpCommand(hIOCP, IOCP_CMD_DISCONNECT, dwConnID);
- }
- BOOL PostIocpSend(HANDLE hIOCP, CONNID dwConnID)
- {
- return PostIocpCommand(hIOCP, IOCP_CMD_SEND, dwConnID);
- }
- BOOL PostIocpClose(HANDLE hIOCP, CONNID dwConnID, int iErrorCode)
- {
- return PostIocpCommand(hIOCP, (EnIocpCommand)iErrorCode, dwConnID);
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////
- int SSO_SetSocketOption(SOCKET sock, int level, int name, LPVOID val, int len)
- {
- return setsockopt(sock, level, name, (CHAR*)val, len);
- }
- int SSO_GetSocketOption(SOCKET sock, int level, int name, LPVOID val, int* len)
- {
- return getsockopt(sock, level, name, (CHAR*)val, len);
- }
- int SSO_IoctlSocket(SOCKET sock, long cmd, u_long* arg)
- {
- return ioctlsocket(sock, cmd, arg);
- }
- int SSO_WSAIoctl(SOCKET sock, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned)
- {
- return ::WSAIoctl(sock, dwIoControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, nullptr, nullptr);
- }
- int SSO_UpdateAcceptContext(SOCKET soClient, SOCKET soBind)
- {
- return setsockopt(soClient, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (CHAR*)&soBind, sizeof(SOCKET));
- }
- int SSO_UpdateConnectContext(SOCKET soClient, int iOption)
- {
- return setsockopt(soClient, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, (CHAR*)&iOption, sizeof(int));
- }
- int SSO_NoBlock(SOCKET sock, BOOL bNoBlock)
- {
- return ioctlsocket(sock, FIONBIO, (ULONG*)&bNoBlock);
- }
- int SSO_NoDelay(SOCKET sock, BOOL bNoDelay)
- {
- return setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (CHAR*)&bNoDelay, sizeof(BOOL));
- }
- int SSO_DontLinger(SOCKET sock, BOOL bDont)
- {
- return setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (CHAR*)&bDont, sizeof(BOOL));
- }
- int SSO_Linger(SOCKET sock, USHORT l_onoff, USHORT l_linger)
- {
- linger ln = {l_onoff, l_linger};
- return setsockopt(sock, SOL_SOCKET, SO_LINGER, (CHAR*)&ln, sizeof(linger));
- }
- int SSO_KeepAlive(SOCKET sock, BOOL bKeepAlive)
- {
- return setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (CHAR*)&bKeepAlive, sizeof(BOOL));
- }
- int SSO_KeepAliveVals(SOCKET sock, u_long onoff, u_long time, u_long interval)
- {
- int result = NO_ERROR;
- tcp_keepalive in = {onoff, time, interval};
- DWORD dwBytes;
- if(::WSAIoctl (
- sock,
- SIO_KEEPALIVE_VALS,
- (LPVOID)&in,
- sizeof(in),
- nullptr,
- 0,
- &dwBytes,
- nullptr,
- nullptr
- ) == SOCKET_ERROR)
- {
- result = ::WSAGetLastError();
- if(result == WSAEWOULDBLOCK)
- result = NO_ERROR;
- }
- return result;
- }
- int SSO_RecvBuffSize(SOCKET sock, int size)
- {
- return setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (CHAR*)&size, sizeof(int));
- }
- int SSO_SendBuffSize(SOCKET sock, int size)
- {
- return setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (CHAR*)&size, sizeof(int));
- }
- int SSO_ReuseAddress(SOCKET sock, BOOL bReuse)
- {
- return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&bReuse, sizeof(BOOL));
- }
- int SSO_UDP_ConnReset(SOCKET sock, BOOL bNewBehavior)
- {
- int result = NO_ERROR;
- DWORD dwBytes;
- if(::WSAIoctl (
- sock,
- SIO_UDP_CONNRESET,
- (LPVOID)&bNewBehavior,
- sizeof(bNewBehavior),
- nullptr,
- 0,
- &dwBytes,
- nullptr,
- nullptr
- ) == SOCKET_ERROR)
- {
- result = ::WSAGetLastError();
- if(result == WSAEWOULDBLOCK)
- result = NO_ERROR;
- }
- return result;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////
- CONNID GenerateConnectionID()
- {
- static volatile CONNID s_dwConnID = 0;
- CONNID dwConnID = ::InterlockedIncrement(&s_dwConnID);
-
- if(dwConnID == 0)
- dwConnID = ::InterlockedIncrement(&s_dwConnID);
- return dwConnID;
- }
- int ManualCloseSocket(SOCKET sock, int iShutdownFlag, BOOL bGraceful, BOOL bReuseAddress)
- {
- if(!bGraceful)
- SSO_Linger(sock, 1, 0);
- if(bReuseAddress)
- SSO_ReuseAddress(sock, bReuseAddress);
- if(iShutdownFlag != 0xFF)
- shutdown(sock, iShutdownFlag);
- return closesocket(sock);
- }
- int PostAccept(LPFN_ACCEPTEX pfnAcceptEx, SOCKET soListen, SOCKET soClient, TBufferObj* pBufferObj, ADDRESS_FAMILY usFamily)
- {
- int result = PostAcceptNotCheck(pfnAcceptEx, soListen, soClient, pBufferObj, usFamily);
- if(result == WSA_IO_PENDING)
- result = NO_ERROR;
- return result;
- }
- int PostAcceptNotCheck(LPFN_ACCEPTEX pfnAcceptEx, SOCKET soListen, SOCKET soClient, TBufferObj* pBufferObj, ADDRESS_FAMILY usFamily)
- {
- int result = NO_ERROR;
- pBufferObj->client = soClient;
- pBufferObj->operation = SO_ACCEPT;
- int iAddrLen = HP_SOCKADDR::AddrSize(usFamily) + 16;
- if(!pfnAcceptEx (
- soListen,
- pBufferObj->client,
- pBufferObj->buff.buf,
- 0,
- iAddrLen,
- iAddrLen,
- nullptr,
- &pBufferObj->ov
- )
- )
- {
- result = ::WSAGetLastError();
- }
- return result;
- }
- int PostConnect(LPFN_CONNECTEX pfnConnectEx, SOCKET soClient, const HP_SOCKADDR& sockAddr, TBufferObj* pBufferObj)
- {
- int result = PostConnectNotCheck(pfnConnectEx, soClient, sockAddr, pBufferObj);
- if(result == WSA_IO_PENDING)
- result = NO_ERROR;
- return result;
- }
- int PostConnectNotCheck(LPFN_CONNECTEX pfnConnectEx, SOCKET soClient, const HP_SOCKADDR& sockAddr, TBufferObj* pBufferObj)
- {
- int result = NO_ERROR;
- pBufferObj->client = soClient;
- pBufferObj->operation = SO_CONNECT;
- if(!pfnConnectEx (
- soClient,
- sockAddr.Addr(),
- sockAddr.AddrSize(),
- nullptr,
- 0,
- nullptr,
- &pBufferObj->ov
- )
- )
- {
- result = ::WSAGetLastError();
- }
- return result;
- }
- int PostSend(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
- {
- int result = PostSendNotCheck(pSocketObj, pBufferObj);
- if(result == WSA_IO_PENDING)
- result = NO_ERROR;
- return result;
- }
- int PostSendNotCheck(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
- {
- int result = NO_ERROR;
- DWORD dwBytes = 0;
- pBufferObj->client = pSocketObj->socket;
- pBufferObj->operation = SO_SEND;
- pBufferObj->ResetSendCounter();
- if(::WSASend(
- pBufferObj->client,
- &pBufferObj->buff,
- 1,
- &dwBytes,
- 0,
- &pBufferObj->ov,
- nullptr
- ) == SOCKET_ERROR)
- {
- result = ::WSAGetLastError();
- }
- return result;
- }
- int PostReceive(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
- {
- int result = PostReceiveNotCheck(pSocketObj, pBufferObj);
- if(result == WSA_IO_PENDING)
- result = NO_ERROR;
- return result;
- }
- int PostReceiveNotCheck(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
- {
- int result = NO_ERROR;
- DWORD dwFlag = 0;
- DWORD dwBytes = 0;
- pBufferObj->client = pSocketObj->socket;
- pBufferObj->operation = SO_RECEIVE;
- if(::WSARecv(
- pBufferObj->client,
- &pBufferObj->buff,
- 1,
- &dwBytes,
- &dwFlag,
- &pBufferObj->ov,
- nullptr
- ) == SOCKET_ERROR)
- {
- result = ::WSAGetLastError();
- }
- return result;
- }
- int PostSendTo(SOCKET sock, TUdpBufferObj* pBufferObj)
- {
- int result = PostSendToNotCheck(sock, pBufferObj);
- if(result == WSA_IO_PENDING)
- result = NO_ERROR;
- return result;
- }
- int PostSendToNotCheck(SOCKET sock, TUdpBufferObj* pBufferObj)
- {
- int result = NO_ERROR;
- DWORD dwBytes = 0;
- pBufferObj->operation = SO_SEND;
- pBufferObj->addrLen = pBufferObj->remoteAddr.AddrSize();
- pBufferObj->ResetSendCounter();
- if(::WSASendTo (
- sock,
- &pBufferObj->buff,
- 1,
- &dwBytes,
- 0,
- pBufferObj->remoteAddr.Addr(),
- pBufferObj->addrLen,
- &pBufferObj->ov,
- nullptr
- ) == SOCKET_ERROR)
- {
- result = ::WSAGetLastError();
- }
- return result;
- }
- int PostReceiveFrom(SOCKET sock, TUdpBufferObj* pBufferObj)
- {
- int result = PostReceiveFromNotCheck(sock, pBufferObj);
- if(result == WSA_IO_PENDING)
- result = NO_ERROR;
- return result;
- }
- int PostReceiveFromNotCheck(SOCKET sock, TUdpBufferObj* pBufferObj)
- {
- int result = NO_ERROR;
- DWORD dwFlag = 0;
- DWORD dwBytes = 0;
- pBufferObj->operation = SO_RECEIVE;
- pBufferObj->addrLen = pBufferObj->remoteAddr.AddrSize();
- pBufferObj->remoteAddr.ZeroAddr();
- if(::WSARecvFrom(
- sock,
- &pBufferObj->buff,
- 1,
- &dwBytes,
- &dwFlag,
- pBufferObj->remoteAddr.Addr(),
- &pBufferObj->addrLen,
- &pBufferObj->ov,
- nullptr
- ) == SOCKET_ERROR)
- {
- result = ::WSAGetLastError();
- }
- return result;
- }
- int NoBlockReceive(TBufferObj* pBufferObj)
- {
- int result = NoBlockReceiveNotCheck(pBufferObj);
- if(result == WSAEWOULDBLOCK)
- result = NO_ERROR;
- return result;
- }
- int NoBlockReceiveNotCheck(TBufferObj* pBufferObj)
- {
- int result = NO_ERROR;
- DWORD dwFlag = 0;
- DWORD dwBytes = 0;
- if(::WSARecv(
- pBufferObj->client,
- &pBufferObj->buff,
- 1,
- &dwBytes,
- &dwFlag,
- nullptr,
- nullptr
- ) == SOCKET_ERROR)
- {
- result = ::WSAGetLastError();
- }
- else
- {
- if(dwBytes > 0)
- pBufferObj->buff.len = dwBytes;
- else
- result = WSAEDISCON;
- }
- return result;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////
- LPCTSTR GetSocketErrorDesc(EnSocketError enCode)
- {
- switch(enCode)
- {
- case SE_OK: return _T("SUCCESS");
- case SE_ILLEGAL_STATE: return _T("Illegal State");
- case SE_INVALID_PARAM: return _T("Invalid Parameter");
- case SE_SOCKET_CREATE: return _T("Create SOCKET Fail");
- case SE_SOCKET_BIND: return _T("Bind SOCKET Fail");
- case SE_SOCKET_PREPARE: return _T("Prepare SOCKET Fail");
- case SE_SOCKET_LISTEN: return _T("Listen SOCKET Fail");
- case SE_CP_CREATE: return _T("Create IOCP Fail");
- case SE_WORKER_THREAD_CREATE: return _T("Create Worker Thread Fail");
- case SE_DETECT_THREAD_CREATE: return _T("Create Detector Thread Fail");
- case SE_SOCKE_ATTACH_TO_CP: return _T("Attach SOCKET to IOCP Fail");
- case SE_CONNECT_SERVER: return _T("Connect to Server Fail");
- case SE_NETWORK: return _T("Network Error");
- case SE_DATA_PROC: return _T("Process Data Error");
- case SE_DATA_SEND: return _T("Send Data Fail");
- case SE_SSL_ENV_NOT_READY: return _T("SSL environment not ready");
- default: ASSERT(FALSE); return _T("UNKNOWN ERROR");
- }
- }
|