工具项目

SocketHelper.cpp 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Author : Bruce Liang
  5. * Website : http://www.jessma.org
  6. * Project : https://github.com/ldcsaa
  7. * Blog : http://www.cnblogs.com/ldcsaa
  8. * Wiki : http://www.oschina.net/p/hp-socket
  9. * QQ Group : 75375912, 44636872
  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. #include "stdafx.h"
  24. #include "../Common/Src/GeneralHelper.h"
  25. #include "../Common/Src/SysHelper.h"
  26. #include "SocketHelper.h"
  27. #include <mstcpip.h>
  28. #pragma comment(lib, "ws2_32")
  29. #if !defined(stscanf_s)
  30. #ifdef _UNICODE
  31. #define stscanf_s swscanf_s
  32. #else
  33. #define stscanf_s sscanf_s
  34. #endif
  35. #endif
  36. const hp_addr hp_addr::ANY_ADDR4(AF_INET, TRUE);
  37. const hp_addr hp_addr::ANY_ADDR6(AF_INET6, TRUE);
  38. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  39. ADDRESS_FAMILY DetermineAddrFamily(LPCTSTR lpszAddress)
  40. {
  41. if (!lpszAddress || lpszAddress[0] == 0)
  42. return AF_UNSPEC;
  43. if(::StrChr(lpszAddress, IPV6_ADDR_SEPARATOR_CHAR))
  44. return AF_INET6;
  45. TCHAR c;
  46. int arr[4];
  47. if(stscanf_s(lpszAddress, _T("%d.%d.%d.%d%c"), &arr[0], &arr[1], &arr[2], &arr[3], &c, 1) != 4)
  48. return AF_UNSPEC;
  49. for(int i = 0; i < 4; i++)
  50. {
  51. if(arr[i] < 0 || arr[i] > 255)
  52. return AF_UNSPEC;
  53. }
  54. return AF_INET;
  55. }
  56. BOOL GetInAddr(LPCTSTR lpszAddress, HP_ADDR& addr)
  57. {
  58. addr.family = DetermineAddrFamily(lpszAddress);
  59. if (addr.family == AF_UNSPEC)
  60. return FALSE;
  61. #if _WIN32_WINNT >= _WIN32_WINNT_VISTA
  62. return (::InetPton(addr.family, lpszAddress, addr.Addr()) == TRUE);
  63. #else
  64. HP_SOCKADDR sockAddr(addr.family);
  65. if(!GetSockAddr(lpszAddress, 0, sockAddr))
  66. return FALSE;
  67. memcpy(addr.Addr(), sockAddr.SinAddr(), addr.AddrSize());
  68. return TRUE;
  69. #endif
  70. }
  71. BOOL GetSockAddr(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr)
  72. {
  73. if(addr.family != AF_INET && addr.family != AF_INET6)
  74. {
  75. ::WSASetLastError(WSAEADDRNOTAVAIL);
  76. return FALSE;
  77. }
  78. int iSize = addr.AddrSize();
  79. if(::WSAStringToAddress((LPTSTR)lpszAddress, addr.family, nullptr, addr.Addr(), &iSize) != NO_ERROR)
  80. return FALSE;
  81. if(usPort != 0)
  82. addr.SetPort(usPort);
  83. return TRUE;
  84. }
  85. BOOL IsIPAddress(LPCTSTR lpszAddress, EnIPAddrType* penType)
  86. {
  87. HP_ADDR addr;
  88. BOOL isOK = GetInAddr(lpszAddress, addr);
  89. if(isOK && penType)
  90. *penType = addr.IsIPv4() ? IPT_IPV4 : IPT_IPV6;
  91. return isOK;
  92. }
  93. BOOL GetIPAddress(LPCTSTR lpszHost, LPTSTR lpszIP, int& iIPLen, EnIPAddrType& enType)
  94. {
  95. HP_SOCKADDR addr;
  96. if(!GetSockAddrByHostName(lpszHost, 0, addr))
  97. return FALSE;
  98. enType = addr.IsIPv4() ? IPT_IPV4 : IPT_IPV6;
  99. USHORT usPort;
  100. ADDRESS_FAMILY usFamily;
  101. return sockaddr_IN_2_A(addr, usFamily, lpszIP, iIPLen, usPort);
  102. }
  103. BOOL GetSockAddrByHostName(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr)
  104. {
  105. addr.family = DetermineAddrFamily(lpszHost);
  106. if(addr.family != AF_UNSPEC)
  107. return GetSockAddr(lpszHost, usPort, addr);
  108. return GetSockAddrByHostNameDirectly(lpszHost, usPort, addr);
  109. }
  110. BOOL GetSockAddrByHostNameDirectly(LPCTSTR lpszHost, USHORT usPort, HP_SOCKADDR& addr)
  111. {
  112. addr.ZeroAddr();
  113. addrinfo* pInfo = nullptr;
  114. addrinfo hints = {0};
  115. hints.ai_flags = AI_ALL;
  116. hints.ai_family = addr.family;
  117. int rs = ::getaddrinfo(CT2A(lpszHost), nullptr, &hints, &pInfo);
  118. if(rs != NO_ERROR)
  119. {
  120. ::WSASetLastError(rs);
  121. return FALSE;
  122. }
  123. BOOL isOK = FALSE;
  124. for(addrinfo* pCur = pInfo; pCur != nullptr; pCur = pCur->ai_next)
  125. {
  126. if(pCur->ai_family == AF_INET || pCur->ai_family == AF_INET6)
  127. {
  128. memcpy(addr.Addr(), pCur->ai_addr, pCur->ai_addrlen);
  129. isOK = TRUE;
  130. break;
  131. }
  132. }
  133. ::freeaddrinfo(pInfo);
  134. if(isOK)
  135. addr.SetPort(usPort);
  136. else
  137. ::WSASetLastError(WSAHOST_NOT_FOUND);
  138. return isOK;
  139. }
  140. BOOL EnumHostIPAddresses(LPCTSTR lpszHost, EnIPAddrType enType, LPTIPAddr** lpppIPAddr, int& iIPAddrCount)
  141. {
  142. *lpppIPAddr = nullptr;
  143. iIPAddrCount = 0;
  144. ADDRESS_FAMILY usFamily = (enType == IPT_ALL ?
  145. AF_UNSPEC : (enType == IPT_IPV4 ?
  146. AF_INET : (enType == IPT_IPV6 ?
  147. AF_INET6 : 0xFF)));
  148. if(usFamily == 0xFF)
  149. {
  150. ::WSASetLastError(WSAEAFNOSUPPORT);
  151. return FALSE;
  152. }
  153. vector<HP_PSOCKADDR> vt;
  154. ADDRESS_FAMILY usFamily2 = DetermineAddrFamily(lpszHost);
  155. if(usFamily2 != AF_UNSPEC)
  156. {
  157. if(usFamily != AF_UNSPEC && usFamily != usFamily2)
  158. {
  159. ::WSASetLastError(WSAHOST_NOT_FOUND);
  160. return FALSE;
  161. }
  162. HP_SOCKADDR addr(usFamily2);
  163. if(!GetSockAddr(lpszHost, 0, addr))
  164. return FALSE;
  165. vt.emplace_back(&addr);
  166. return RetrieveSockAddrIPAddresses(vt, lpppIPAddr, iIPAddrCount);
  167. }
  168. addrinfo* pInfo = nullptr;
  169. addrinfo hints = {0};
  170. hints.ai_flags = AI_ALL;
  171. hints.ai_family = usFamily;
  172. int rs = ::getaddrinfo(CT2A(lpszHost), nullptr, &hints, &pInfo);
  173. if(rs != NO_ERROR)
  174. {
  175. ::WSASetLastError(rs);
  176. return FALSE;
  177. }
  178. for(addrinfo* pCur = pInfo; pCur != nullptr; pCur = pCur->ai_next)
  179. {
  180. if(pCur->ai_family == AF_INET || pCur->ai_family == AF_INET6)
  181. vt.emplace_back((HP_PSOCKADDR)pCur->ai_addr);
  182. }
  183. BOOL isOK = RetrieveSockAddrIPAddresses(vt, lpppIPAddr, iIPAddrCount);
  184. ::freeaddrinfo(pInfo);
  185. if(!isOK) ::WSASetLastError(WSAHOST_NOT_FOUND);
  186. return isOK;
  187. }
  188. BOOL RetrieveSockAddrIPAddresses(const vector<HP_PSOCKADDR>& vt, LPTIPAddr** lpppIPAddr, int& iIPAddrCount)
  189. {
  190. iIPAddrCount = (int)vt.size();
  191. if(iIPAddrCount == 0) return FALSE;
  192. HP_PSOCKADDR pSockAddr;
  193. ADDRESS_FAMILY usFamily;
  194. USHORT usPort;
  195. int iAddrLength;
  196. LPTSTR lpszAddr;
  197. LPTIPAddr lpItem;
  198. (*lpppIPAddr) = new LPTIPAddr[iIPAddrCount + 1];
  199. (*lpppIPAddr)[iIPAddrCount] = nullptr;
  200. for(int i = 0; i < iIPAddrCount; i++)
  201. {
  202. pSockAddr = vt[i];
  203. iAddrLength = HP_SOCKADDR::AddrMinStrLength(pSockAddr->family) + 6;
  204. lpszAddr = new TCHAR[iAddrLength];
  205. VERIFY(sockaddr_IN_2_A(*vt[i], usFamily, lpszAddr, iAddrLength, usPort));
  206. lpItem = new TIPAddr;
  207. lpItem->type = pSockAddr->IsIPv4() ? IPT_IPV4 : IPT_IPV6;
  208. lpItem->address = lpszAddr;
  209. (*lpppIPAddr)[i] = lpItem;
  210. }
  211. return TRUE;
  212. }
  213. BOOL FreeHostIPAddresses(LPTIPAddr* lppIPAddr)
  214. {
  215. if(!lppIPAddr) return FALSE;
  216. LPTIPAddr p;
  217. LPTIPAddr* lppCur = lppIPAddr;
  218. while((p = *lppCur++) != nullptr)
  219. {
  220. delete[] p->address;
  221. delete p;
  222. }
  223. delete[] lppIPAddr;
  224. return TRUE;
  225. }
  226. BOOL sockaddr_IN_2_A(const HP_SOCKADDR& addr, ADDRESS_FAMILY& usFamily, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  227. {
  228. BOOL isOK = FALSE;
  229. usFamily = addr.family;
  230. usPort = addr.Port();
  231. #if _WIN32_WINNT >= _WIN32_WINNT_VISTA
  232. if(::InetNtop(addr.family, addr.SinAddr(), lpszAddress, iAddressLen))
  233. {
  234. iAddressLen = lstrlen(lpszAddress) + 1;
  235. isOK = TRUE;
  236. }
  237. else
  238. {
  239. if(::WSAGetLastError() == ERROR_INVALID_PARAMETER)
  240. iAddressLen = HP_SOCKADDR::AddrMinStrLength(usFamily);
  241. }
  242. #else
  243. if(::WSAAddressToString((LPSOCKADDR)addr.Addr(), addr.AddrSize(), nullptr, lpszAddress, (LPDWORD)&iAddressLen) == NO_ERROR)
  244. {
  245. LPTSTR lpszEnd = nullptr;
  246. BOOL bIPv6 = addr.IsIPv6();
  247. BOOL bHasPort = (addr.Port() != 0);
  248. if(!bIPv6)
  249. {
  250. if(bHasPort)
  251. lpszEnd = ::StrChr(lpszAddress, PORT_SEPARATOR_CHAR);
  252. }
  253. else
  254. {
  255. if(bHasPort)
  256. {
  257. static const TCHAR s_szBrk[] = {IPV6_ADDR_END_CHAR, IPV6_ZONE_INDEX_CHAR, 0};
  258. ASSERT(lpszAddress[0] == IPV6_ADDR_BEGIN_CHAR);
  259. lpszEnd = ::StrPBrk(lpszAddress, s_szBrk);
  260. }
  261. else
  262. {
  263. lpszEnd = ::StrChr(lpszAddress, IPV6_ZONE_INDEX_CHAR);
  264. }
  265. }
  266. ASSERT(!bHasPort || lpszEnd);
  267. if(lpszEnd)
  268. {
  269. lpszEnd[0] = 0;
  270. iAddressLen = lpszEnd - lpszAddress;
  271. }
  272. if(bIPv6 && bHasPort)
  273. memcpy(lpszAddress, (lpszAddress + 1), iAddressLen * sizeof(TCHAR));
  274. else
  275. ++iAddressLen;
  276. isOK = TRUE;
  277. }
  278. #endif
  279. return isOK;
  280. }
  281. BOOL sockaddr_A_2_IN(LPCTSTR lpszAddress, USHORT usPort, HP_SOCKADDR& addr)
  282. {
  283. addr.family = DetermineAddrFamily(lpszAddress);
  284. return GetSockAddr(lpszAddress, usPort, addr);
  285. }
  286. BOOL GetSocketAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort, BOOL bLocal)
  287. {
  288. HP_SOCKADDR addr;
  289. int addr_len = addr.AddrSize();
  290. int result = bLocal ? getsockname(socket, addr.Addr(), &addr_len) : getpeername(socket, addr.Addr(), &addr_len);
  291. if(result != NO_ERROR)
  292. return FALSE;
  293. ADDRESS_FAMILY usFamily;
  294. return sockaddr_IN_2_A(addr, usFamily, lpszAddress, iAddressLen, usPort);
  295. }
  296. BOOL GetSocketLocalAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  297. {
  298. return GetSocketAddress(socket, lpszAddress, iAddressLen, usPort, TRUE);
  299. }
  300. BOOL GetSocketRemoteAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  301. {
  302. return GetSocketAddress(socket, lpszAddress, iAddressLen, usPort, FALSE);
  303. }
  304. ULONGLONG NToH64(ULONGLONG value)
  305. {
  306. return (((ULONGLONG)ntohl((u_long)((value << 32) >> 32))) << 32) | ntohl((u_long)(value >> 32));
  307. }
  308. ULONGLONG HToN64(ULONGLONG value)
  309. {
  310. return (((ULONGLONG)htonl((u_long)((value << 32) >> 32))) << 32) | htonl((u_long)(value >> 32));
  311. }
  312. PVOID GetExtensionFuncPtr(SOCKET sock, GUID guid)
  313. {
  314. DWORD dwBytes;
  315. PVOID pfn = nullptr;
  316. ::WSAIoctl (
  317. sock,
  318. SIO_GET_EXTENSION_FUNCTION_POINTER,
  319. &guid,
  320. sizeof(guid),
  321. &pfn,
  322. sizeof(pfn),
  323. &dwBytes,
  324. nullptr,
  325. nullptr
  326. );
  327. return pfn;
  328. }
  329. LPFN_ACCEPTEX Get_AcceptEx_FuncPtr(SOCKET sock)
  330. {
  331. GUID guid = WSAID_ACCEPTEX;
  332. return (LPFN_ACCEPTEX)GetExtensionFuncPtr(sock, guid);
  333. }
  334. LPFN_GETACCEPTEXSOCKADDRS Get_GetAcceptExSockaddrs_FuncPtr(SOCKET sock)
  335. {
  336. GUID guid = WSAID_GETACCEPTEXSOCKADDRS;
  337. return (LPFN_GETACCEPTEXSOCKADDRS)GetExtensionFuncPtr(sock, guid);
  338. }
  339. LPFN_CONNECTEX Get_ConnectEx_FuncPtr(SOCKET sock)
  340. {
  341. GUID guid = WSAID_CONNECTEX;
  342. return (LPFN_CONNECTEX)GetExtensionFuncPtr(sock, guid);
  343. }
  344. LPFN_TRANSMITFILE Get_TransmitFile_FuncPtr(SOCKET sock)
  345. {
  346. GUID guid = WSAID_TRANSMITFILE;
  347. return (LPFN_TRANSMITFILE)GetExtensionFuncPtr(sock, guid);
  348. }
  349. LPFN_DISCONNECTEX Get_DisconnectEx_FuncPtr (SOCKET sock)
  350. {
  351. GUID guid = WSAID_DISCONNECTEX;
  352. return (LPFN_DISCONNECTEX)GetExtensionFuncPtr(sock, guid);
  353. }
  354. HRESULT ReadSmallFile(LPCTSTR lpszFileName, CAtlFile& file, CAtlFileMapping<>& fmap, DWORD dwMaxFileSize)
  355. {
  356. ASSERT(lpszFileName != nullptr);
  357. HRESULT hr = file.Create(lpszFileName, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING);
  358. if(SUCCEEDED(hr))
  359. {
  360. ULONGLONG ullLen;
  361. hr = file.GetSize(ullLen);
  362. if(SUCCEEDED(hr))
  363. {
  364. if(ullLen > 0 && ullLen <= dwMaxFileSize)
  365. hr = fmap.MapFile(file);
  366. else if(ullLen == 0)
  367. hr = HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
  368. else
  369. hr = HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
  370. }
  371. }
  372. return hr;
  373. }
  374. HRESULT MakeSmallFilePackage(LPCTSTR lpszFileName, CAtlFile& file, CAtlFileMapping<>& fmap, WSABUF szBuf[3], const LPWSABUF pHead, const LPWSABUF pTail)
  375. {
  376. DWORD dwMaxFileSize = MAX_SMALL_FILE_SIZE - (pHead ? pHead->len : 0) - (pTail ? pTail->len : 0);
  377. ASSERT(dwMaxFileSize <= MAX_SMALL_FILE_SIZE);
  378. HRESULT hr = ReadSmallFile(lpszFileName, file, fmap, dwMaxFileSize);
  379. if(SUCCEEDED(hr))
  380. {
  381. szBuf[1].len = (ULONG)fmap.GetMappingSize();
  382. szBuf[1].buf = fmap;
  383. if(pHead) memcpy(&szBuf[0], pHead, sizeof(WSABUF));
  384. else memset(&szBuf[0], 0, sizeof(WSABUF));
  385. if(pTail) memcpy(&szBuf[2], pTail, sizeof(WSABUF));
  386. else memset(&szBuf[2], 0, sizeof(WSABUF));
  387. }
  388. return hr;
  389. }
  390. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  391. BOOL PostIocpCommand(HANDLE hIOCP, EnIocpCommand enCmd, ULONG_PTR ulParam)
  392. {
  393. return ::PostQueuedCompletionStatus(hIOCP, enCmd, ulParam, nullptr);
  394. }
  395. BOOL PostIocpExit(HANDLE hIOCP)
  396. {
  397. return PostIocpCommand(hIOCP, IOCP_CMD_EXIT, 0);
  398. }
  399. BOOL PostIocpAccept(HANDLE hIOCP)
  400. {
  401. return PostIocpCommand(hIOCP, IOCP_CMD_ACCEPT, 0);
  402. }
  403. BOOL PostIocpDisconnect(HANDLE hIOCP, CONNID dwConnID)
  404. {
  405. return PostIocpCommand(hIOCP, IOCP_CMD_DISCONNECT, dwConnID);
  406. }
  407. BOOL PostIocpSend(HANDLE hIOCP, CONNID dwConnID)
  408. {
  409. return PostIocpCommand(hIOCP, IOCP_CMD_SEND, dwConnID);
  410. }
  411. BOOL PostIocpClose(HANDLE hIOCP, CONNID dwConnID, int iErrorCode)
  412. {
  413. return PostIocpCommand(hIOCP, (EnIocpCommand)iErrorCode, dwConnID);
  414. }
  415. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  416. int SSO_SetSocketOption(SOCKET sock, int level, int name, LPVOID val, int len)
  417. {
  418. return setsockopt(sock, level, name, (CHAR*)val, len);
  419. }
  420. int SSO_GetSocketOption(SOCKET sock, int level, int name, LPVOID val, int* len)
  421. {
  422. return getsockopt(sock, level, name, (CHAR*)val, len);
  423. }
  424. int SSO_IoctlSocket(SOCKET sock, long cmd, u_long* arg)
  425. {
  426. return ioctlsocket(sock, cmd, arg);
  427. }
  428. int SSO_WSAIoctl(SOCKET sock, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned)
  429. {
  430. return ::WSAIoctl(sock, dwIoControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, nullptr, nullptr);
  431. }
  432. int SSO_UpdateAcceptContext(SOCKET soClient, SOCKET soBind)
  433. {
  434. return setsockopt(soClient, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (CHAR*)&soBind, sizeof(SOCKET));
  435. }
  436. int SSO_UpdateConnectContext(SOCKET soClient, int iOption)
  437. {
  438. return setsockopt(soClient, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, (CHAR*)&iOption, sizeof(int));
  439. }
  440. int SSO_NoBlock(SOCKET sock, BOOL bNoBlock)
  441. {
  442. return ioctlsocket(sock, FIONBIO, (ULONG*)&bNoBlock);
  443. }
  444. int SSO_NoDelay(SOCKET sock, BOOL bNoDelay)
  445. {
  446. return setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (CHAR*)&bNoDelay, sizeof(BOOL));
  447. }
  448. int SSO_DontLinger(SOCKET sock, BOOL bDont)
  449. {
  450. return setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (CHAR*)&bDont, sizeof(BOOL));
  451. }
  452. int SSO_Linger(SOCKET sock, USHORT l_onoff, USHORT l_linger)
  453. {
  454. linger ln = {l_onoff, l_linger};
  455. return setsockopt(sock, SOL_SOCKET, SO_LINGER, (CHAR*)&ln, sizeof(linger));
  456. }
  457. int SSO_KeepAlive(SOCKET sock, BOOL bKeepAlive)
  458. {
  459. return setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (CHAR*)&bKeepAlive, sizeof(BOOL));
  460. }
  461. int SSO_KeepAliveVals(SOCKET sock, u_long onoff, u_long time, u_long interval)
  462. {
  463. int result = NO_ERROR;
  464. tcp_keepalive in = {onoff, time, interval};
  465. DWORD dwBytes;
  466. if(::WSAIoctl (
  467. sock,
  468. SIO_KEEPALIVE_VALS,
  469. (LPVOID)&in,
  470. sizeof(in),
  471. nullptr,
  472. 0,
  473. &dwBytes,
  474. nullptr,
  475. nullptr
  476. ) == SOCKET_ERROR)
  477. {
  478. result = ::WSAGetLastError();
  479. if(result == WSAEWOULDBLOCK)
  480. result = NO_ERROR;
  481. }
  482. return result;
  483. }
  484. int SSO_RecvBuffSize(SOCKET sock, int size)
  485. {
  486. return setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (CHAR*)&size, sizeof(int));
  487. }
  488. int SSO_SendBuffSize(SOCKET sock, int size)
  489. {
  490. return setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (CHAR*)&size, sizeof(int));
  491. }
  492. int SSO_ReuseAddress(SOCKET sock, BOOL bReuse)
  493. {
  494. return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&bReuse, sizeof(BOOL));
  495. }
  496. int SSO_UDP_ConnReset(SOCKET sock, BOOL bNewBehavior)
  497. {
  498. int result = NO_ERROR;
  499. DWORD dwBytes;
  500. if(::WSAIoctl (
  501. sock,
  502. SIO_UDP_CONNRESET,
  503. (LPVOID)&bNewBehavior,
  504. sizeof(bNewBehavior),
  505. nullptr,
  506. 0,
  507. &dwBytes,
  508. nullptr,
  509. nullptr
  510. ) == SOCKET_ERROR)
  511. {
  512. result = ::WSAGetLastError();
  513. if(result == WSAEWOULDBLOCK)
  514. result = NO_ERROR;
  515. }
  516. return result;
  517. }
  518. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  519. CONNID GenerateConnectionID()
  520. {
  521. static volatile CONNID s_dwConnID = 0;
  522. CONNID dwConnID = ::InterlockedIncrement(&s_dwConnID);
  523. if(dwConnID == 0)
  524. dwConnID = ::InterlockedIncrement(&s_dwConnID);
  525. return dwConnID;
  526. }
  527. int ManualCloseSocket(SOCKET sock, int iShutdownFlag, BOOL bGraceful, BOOL bReuseAddress)
  528. {
  529. if(!bGraceful)
  530. SSO_Linger(sock, 1, 0);
  531. if(bReuseAddress)
  532. SSO_ReuseAddress(sock, bReuseAddress);
  533. if(iShutdownFlag != 0xFF)
  534. shutdown(sock, iShutdownFlag);
  535. return closesocket(sock);
  536. }
  537. int PostAccept(LPFN_ACCEPTEX pfnAcceptEx, SOCKET soListen, SOCKET soClient, TBufferObj* pBufferObj, ADDRESS_FAMILY usFamily)
  538. {
  539. int result = PostAcceptNotCheck(pfnAcceptEx, soListen, soClient, pBufferObj, usFamily);
  540. if(result == WSA_IO_PENDING)
  541. result = NO_ERROR;
  542. return result;
  543. }
  544. int PostAcceptNotCheck(LPFN_ACCEPTEX pfnAcceptEx, SOCKET soListen, SOCKET soClient, TBufferObj* pBufferObj, ADDRESS_FAMILY usFamily)
  545. {
  546. int result = NO_ERROR;
  547. pBufferObj->client = soClient;
  548. pBufferObj->operation = SO_ACCEPT;
  549. int iAddrLen = HP_SOCKADDR::AddrSize(usFamily) + 16;
  550. if(!pfnAcceptEx (
  551. soListen,
  552. pBufferObj->client,
  553. pBufferObj->buff.buf,
  554. 0,
  555. iAddrLen,
  556. iAddrLen,
  557. nullptr,
  558. &pBufferObj->ov
  559. )
  560. )
  561. {
  562. result = ::WSAGetLastError();
  563. }
  564. return result;
  565. }
  566. int PostConnect(LPFN_CONNECTEX pfnConnectEx, SOCKET soClient, const HP_SOCKADDR& sockAddr, TBufferObj* pBufferObj)
  567. {
  568. int result = PostConnectNotCheck(pfnConnectEx, soClient, sockAddr, pBufferObj);
  569. if(result == WSA_IO_PENDING)
  570. result = NO_ERROR;
  571. return result;
  572. }
  573. int PostConnectNotCheck(LPFN_CONNECTEX pfnConnectEx, SOCKET soClient, const HP_SOCKADDR& sockAddr, TBufferObj* pBufferObj)
  574. {
  575. int result = NO_ERROR;
  576. pBufferObj->client = soClient;
  577. pBufferObj->operation = SO_CONNECT;
  578. if(!pfnConnectEx (
  579. soClient,
  580. sockAddr.Addr(),
  581. sockAddr.AddrSize(),
  582. nullptr,
  583. 0,
  584. nullptr,
  585. &pBufferObj->ov
  586. )
  587. )
  588. {
  589. result = ::WSAGetLastError();
  590. }
  591. return result;
  592. }
  593. int PostSend(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
  594. {
  595. int result = PostSendNotCheck(pSocketObj, pBufferObj);
  596. if(result == WSA_IO_PENDING)
  597. result = NO_ERROR;
  598. return result;
  599. }
  600. int PostSendNotCheck(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
  601. {
  602. int result = NO_ERROR;
  603. DWORD dwBytes = 0;
  604. pBufferObj->client = pSocketObj->socket;
  605. pBufferObj->operation = SO_SEND;
  606. pBufferObj->ResetSendCounter();
  607. if(::WSASend(
  608. pBufferObj->client,
  609. &pBufferObj->buff,
  610. 1,
  611. &dwBytes,
  612. 0,
  613. &pBufferObj->ov,
  614. nullptr
  615. ) == SOCKET_ERROR)
  616. {
  617. result = ::WSAGetLastError();
  618. }
  619. return result;
  620. }
  621. int PostReceive(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
  622. {
  623. int result = PostReceiveNotCheck(pSocketObj, pBufferObj);
  624. if(result == WSA_IO_PENDING)
  625. result = NO_ERROR;
  626. return result;
  627. }
  628. int PostReceiveNotCheck(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
  629. {
  630. int result = NO_ERROR;
  631. DWORD dwFlag = 0;
  632. DWORD dwBytes = 0;
  633. pBufferObj->client = pSocketObj->socket;
  634. pBufferObj->operation = SO_RECEIVE;
  635. if(::WSARecv(
  636. pBufferObj->client,
  637. &pBufferObj->buff,
  638. 1,
  639. &dwBytes,
  640. &dwFlag,
  641. &pBufferObj->ov,
  642. nullptr
  643. ) == SOCKET_ERROR)
  644. {
  645. result = ::WSAGetLastError();
  646. }
  647. return result;
  648. }
  649. int PostSendTo(SOCKET sock, TUdpBufferObj* pBufferObj)
  650. {
  651. int result = PostSendToNotCheck(sock, pBufferObj);
  652. if(result == WSA_IO_PENDING)
  653. result = NO_ERROR;
  654. return result;
  655. }
  656. int PostSendToNotCheck(SOCKET sock, TUdpBufferObj* pBufferObj)
  657. {
  658. int result = NO_ERROR;
  659. DWORD dwBytes = 0;
  660. pBufferObj->operation = SO_SEND;
  661. pBufferObj->addrLen = pBufferObj->remoteAddr.AddrSize();
  662. pBufferObj->ResetSendCounter();
  663. if(::WSASendTo (
  664. sock,
  665. &pBufferObj->buff,
  666. 1,
  667. &dwBytes,
  668. 0,
  669. pBufferObj->remoteAddr.Addr(),
  670. pBufferObj->addrLen,
  671. &pBufferObj->ov,
  672. nullptr
  673. ) == SOCKET_ERROR)
  674. {
  675. result = ::WSAGetLastError();
  676. }
  677. return result;
  678. }
  679. int PostReceiveFrom(SOCKET sock, TUdpBufferObj* pBufferObj)
  680. {
  681. int result = PostReceiveFromNotCheck(sock, pBufferObj);
  682. if(result == WSA_IO_PENDING)
  683. result = NO_ERROR;
  684. return result;
  685. }
  686. int PostReceiveFromNotCheck(SOCKET sock, TUdpBufferObj* pBufferObj)
  687. {
  688. int result = NO_ERROR;
  689. DWORD dwFlag = 0;
  690. DWORD dwBytes = 0;
  691. pBufferObj->operation = SO_RECEIVE;
  692. pBufferObj->addrLen = pBufferObj->remoteAddr.AddrSize();
  693. pBufferObj->remoteAddr.ZeroAddr();
  694. if(::WSARecvFrom(
  695. sock,
  696. &pBufferObj->buff,
  697. 1,
  698. &dwBytes,
  699. &dwFlag,
  700. pBufferObj->remoteAddr.Addr(),
  701. &pBufferObj->addrLen,
  702. &pBufferObj->ov,
  703. nullptr
  704. ) == SOCKET_ERROR)
  705. {
  706. result = ::WSAGetLastError();
  707. }
  708. return result;
  709. }
  710. int NoBlockReceive(TBufferObj* pBufferObj)
  711. {
  712. int result = NoBlockReceiveNotCheck(pBufferObj);
  713. if(result == WSAEWOULDBLOCK)
  714. result = NO_ERROR;
  715. return result;
  716. }
  717. int NoBlockReceiveNotCheck(TBufferObj* pBufferObj)
  718. {
  719. int result = NO_ERROR;
  720. DWORD dwFlag = 0;
  721. DWORD dwBytes = 0;
  722. if(::WSARecv(
  723. pBufferObj->client,
  724. &pBufferObj->buff,
  725. 1,
  726. &dwBytes,
  727. &dwFlag,
  728. nullptr,
  729. nullptr
  730. ) == SOCKET_ERROR)
  731. {
  732. result = ::WSAGetLastError();
  733. }
  734. else
  735. {
  736. if(dwBytes > 0)
  737. pBufferObj->buff.len = dwBytes;
  738. else
  739. result = WSAEDISCON;
  740. }
  741. return result;
  742. }
  743. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  744. LPCTSTR GetSocketErrorDesc(EnSocketError enCode)
  745. {
  746. switch(enCode)
  747. {
  748. case SE_OK: return _T("SUCCESS");
  749. case SE_ILLEGAL_STATE: return _T("Illegal State");
  750. case SE_INVALID_PARAM: return _T("Invalid Parameter");
  751. case SE_SOCKET_CREATE: return _T("Create SOCKET Fail");
  752. case SE_SOCKET_BIND: return _T("Bind SOCKET Fail");
  753. case SE_SOCKET_PREPARE: return _T("Prepare SOCKET Fail");
  754. case SE_SOCKET_LISTEN: return _T("Listen SOCKET Fail");
  755. case SE_CP_CREATE: return _T("Create IOCP Fail");
  756. case SE_WORKER_THREAD_CREATE: return _T("Create Worker Thread Fail");
  757. case SE_DETECT_THREAD_CREATE: return _T("Create Detector Thread Fail");
  758. case SE_SOCKE_ATTACH_TO_CP: return _T("Attach SOCKET to IOCP Fail");
  759. case SE_CONNECT_SERVER: return _T("Connect to Server Fail");
  760. case SE_NETWORK: return _T("Network Error");
  761. case SE_DATA_PROC: return _T("Process Data Error");
  762. case SE_DATA_SEND: return _T("Send Data Fail");
  763. case SE_SSL_ENV_NOT_READY: return _T("SSL environment not ready");
  764. default: ASSERT(FALSE); return _T("UNKNOWN ERROR");
  765. }
  766. }