SocketHelper.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Version : 4.2.1
  5. * Author : Bruce Liang
  6. * Website : http://www.jessma.org
  7. * Project : https://github.com/ldcsaa
  8. * Blog : http://www.cnblogs.com/ldcsaa
  9. * Wiki : http://www.oschina.net/p/hp-socket
  10. * QQ Group : 75375912
  11. *
  12. * Licensed under the Apache License, Version 2.0 (the "License");
  13. * you may not use this file except in compliance with the License.
  14. * You may obtain a copy of the License at
  15. *
  16. * http://www.apache.org/licenses/LICENSE-2.0
  17. *
  18. * Unless required by applicable law or agreed to in writing, software
  19. * distributed under the License is distributed on an "AS IS" BASIS,
  20. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21. * See the License for the specific language governing permissions and
  22. * limitations under the License.
  23. */
  24. #include "stdafx.h"
  25. #include "../../Common/Src/GeneralHelper.h"
  26. #include "../../Common/Src/SysHelper.h"
  27. #include "SocketHelper.h"
  28. #include <mstcpip.h>
  29. #pragma comment(lib, "ws2_32")
  30. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  31. DWORD GetDefaultWorkerThreadCount()
  32. {
  33. static DWORD s_dwtc = min((::SysGetNumberOfProcessors() * 2 + 2), MAX_WORKER_THREAD_COUNT);
  34. return s_dwtc;
  35. }
  36. DWORD GetDefaultTcpSocketBufferSize()
  37. {
  38. static DWORD s_dtsbs = ::SysGetPageSize();
  39. return s_dtsbs;
  40. }
  41. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  42. ULONG GetIPv4InAddr(LPCTSTR lpszAddress)
  43. {
  44. if (!lpszAddress || lpszAddress[0] == 0)
  45. return INADDR_NONE;
  46. #if _WIN32_WINNT >= _WIN32_WINNT_VISTA
  47. IN_ADDR addr;
  48. if (::InetPton(AF_INET, lpszAddress, &addr.s_addr) == 1)
  49. return addr.s_addr;
  50. return INADDR_NONE;
  51. #else
  52. return ::inet_addr(CT2A(lpszAddress));
  53. #endif
  54. }
  55. BOOL IsIPAddress(LPCTSTR lpszAddress)
  56. {
  57. return GetIPv4InAddr(lpszAddress) != INADDR_NONE;
  58. }
  59. BOOL GetIPAddress(LPCTSTR lpszHost, LPTSTR lpszIP, int& iIPLen)
  60. {
  61. BOOL isOK = TRUE;
  62. if(IsIPAddress(lpszHost))
  63. {
  64. int iHostLen = lstrlen(lpszHost);
  65. if(iHostLen > 0)
  66. ++iHostLen;
  67. if(iHostLen > 0 && iIPLen >= iHostLen)
  68. lstrcpy(lpszIP, lpszHost);
  69. else
  70. isOK = FALSE;
  71. iIPLen = iHostLen;
  72. }
  73. else
  74. {
  75. IN_ADDR addr;
  76. if(GetOptimalIPByHostName(lpszHost, addr))
  77. isOK = IN_ADDR_2_IP(addr, lpszIP, iIPLen);
  78. else
  79. isOK = FALSE;
  80. }
  81. return isOK;
  82. }
  83. BOOL GetOptimalIPByHostName(LPCTSTR lpszHost, IN_ADDR& addr)
  84. {
  85. addr.s_addr = 0;
  86. addrinfo* pInfo = nullptr;
  87. addrinfo hints = {0};
  88. hints.ai_flags = AI_ALL;
  89. hints.ai_family = AF_INET;
  90. int rs = ::getaddrinfo((CT2A)lpszHost, nullptr, &hints, &pInfo);
  91. if(rs == NO_ERROR)
  92. {
  93. IN_ADDR inAddr;
  94. ULONG addrs[3] = {0};
  95. char** pptr = nullptr;
  96. for(addrinfo* pCur = pInfo; pCur != nullptr; pCur = pCur->ai_next)
  97. {
  98. if(pCur->ai_family == AF_INET)
  99. {
  100. inAddr = ((SOCKADDR_IN*)(pCur->ai_addr))->sin_addr;
  101. UCHAR a = inAddr.s_net;
  102. UCHAR b = inAddr.s_host;
  103. if(addrs[0] == 0 && a == 127)
  104. {
  105. addrs[0] = inAddr.s_addr;
  106. break;
  107. }
  108. else if( addrs[1] == 0 &&
  109. (
  110. (a == 10) ||
  111. (a == 172 && b >= 16 && b <= 31) ||
  112. (a == 192 && b == 168)
  113. )
  114. )
  115. addrs[1] = inAddr.s_addr;
  116. else if(addrs[2] == 0)
  117. addrs[2] = inAddr.s_addr;
  118. }
  119. }
  120. ::freeaddrinfo(pInfo);
  121. for(int i = 0; i < 3; i++)
  122. {
  123. if(addrs[i] != 0)
  124. {
  125. addr.s_addr = addrs[i];
  126. break;
  127. }
  128. }
  129. }
  130. return addr.s_addr != 0;
  131. }
  132. BOOL IN_ADDR_2_IP(const IN_ADDR& addr, LPTSTR lpszAddress, int& iAddressLen)
  133. {
  134. BOOL isOK = TRUE;
  135. TCHAR szAddr[16];
  136. wsprintf(szAddr, _T("%hu.%hu.%hu.%hu"), addr.s_net, addr.s_host, addr.s_lh, addr.s_impno);
  137. int iIPLen = lstrlen(szAddr) + 1;
  138. if(iAddressLen >= iIPLen)
  139. memcpy(lpszAddress, szAddr, iIPLen * sizeof(TCHAR));
  140. else
  141. isOK = FALSE;
  142. iAddressLen = iIPLen;
  143. return isOK;
  144. }
  145. BOOL sockaddr_IN_2_A(const SOCKADDR_IN& addr, ADDRESS_FAMILY& usFamily, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  146. {
  147. usFamily = addr.sin_family;
  148. usPort = ntohs(addr.sin_port);
  149. return IN_ADDR_2_IP(addr.sin_addr, lpszAddress, iAddressLen);
  150. }
  151. BOOL sockaddr_A_2_IN(ADDRESS_FAMILY usFamily, LPCTSTR lpszAddress, USHORT usPort, SOCKADDR_IN& addr)
  152. {
  153. ASSERT(usFamily == AF_INET);
  154. addr.sin_family = usFamily;
  155. addr.sin_port = htons(usPort);
  156. addr.sin_addr.s_addr = GetIPv4InAddr(lpszAddress);
  157. return addr.sin_addr.s_addr != INADDR_NONE;
  158. }
  159. BOOL GetSocketAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort, BOOL bLocal)
  160. {
  161. sockaddr addr;
  162. int addr_len = sizeof(addr);
  163. int result = bLocal ? getsockname(socket, &addr, &addr_len) : getpeername(socket, &addr, &addr_len);
  164. if(result == NO_ERROR)
  165. {
  166. ADDRESS_FAMILY usFamily;
  167. return sockaddr_IN_2_A((sockaddr_in&)addr, usFamily, lpszAddress, iAddressLen, usPort);
  168. }
  169. return FALSE;
  170. }
  171. BOOL GetSocketLocalAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  172. {
  173. return GetSocketAddress(socket, lpszAddress, iAddressLen, usPort, TRUE);
  174. }
  175. BOOL GetSocketRemoteAddress(SOCKET socket, LPTSTR lpszAddress, int& iAddressLen, USHORT& usPort)
  176. {
  177. return GetSocketAddress(socket, lpszAddress, iAddressLen, usPort, FALSE);
  178. }
  179. ULONGLONG NToH64(ULONGLONG value)
  180. {
  181. return (((ULONGLONG)ntohl((u_long)((value << 32) >> 32))) << 32) | ntohl((u_long)(value >> 32));
  182. }
  183. ULONGLONG HToN64(ULONGLONG value)
  184. {
  185. return (((ULONGLONG)htonl((u_long)((value << 32) >> 32))) << 32) | htonl((u_long)(value >> 32));
  186. }
  187. PVOID GetExtensionFuncPtr(SOCKET sock, GUID guid)
  188. {
  189. DWORD dwBytes;
  190. PVOID pfn = nullptr;
  191. ::WSAIoctl (
  192. sock,
  193. SIO_GET_EXTENSION_FUNCTION_POINTER,
  194. &guid,
  195. sizeof(guid),
  196. &pfn,
  197. sizeof(pfn),
  198. &dwBytes,
  199. nullptr,
  200. nullptr
  201. );
  202. return pfn;
  203. }
  204. LPFN_ACCEPTEX Get_AcceptEx_FuncPtr(SOCKET sock)
  205. {
  206. GUID guid = WSAID_ACCEPTEX;
  207. return (LPFN_ACCEPTEX)GetExtensionFuncPtr(sock, guid);
  208. }
  209. LPFN_GETACCEPTEXSOCKADDRS Get_GetAcceptExSockaddrs_FuncPtr(SOCKET sock)
  210. {
  211. GUID guid = WSAID_GETACCEPTEXSOCKADDRS;
  212. return (LPFN_GETACCEPTEXSOCKADDRS)GetExtensionFuncPtr(sock, guid);
  213. }
  214. LPFN_CONNECTEX Get_ConnectEx_FuncPtr(SOCKET sock)
  215. {
  216. GUID guid = WSAID_CONNECTEX;
  217. return (LPFN_CONNECTEX)GetExtensionFuncPtr(sock, guid);
  218. }
  219. LPFN_TRANSMITFILE Get_TransmitFile_FuncPtr(SOCKET sock)
  220. {
  221. GUID guid = WSAID_TRANSMITFILE;
  222. return (LPFN_TRANSMITFILE)GetExtensionFuncPtr(sock, guid);
  223. }
  224. LPFN_DISCONNECTEX Get_DisconnectEx_FuncPtr (SOCKET sock)
  225. {
  226. GUID guid = WSAID_DISCONNECTEX;
  227. return (LPFN_DISCONNECTEX)GetExtensionFuncPtr(sock, guid);
  228. }
  229. HRESULT ReadSmallFile(LPCTSTR lpszFileName, CAtlFile& file, CAtlFileMapping<>& fmap, DWORD dwMaxFileSize)
  230. {
  231. ASSERT(lpszFileName != nullptr);
  232. HRESULT hr = file.Create(lpszFileName, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING);
  233. if(SUCCEEDED(hr))
  234. {
  235. ULONGLONG ullLen;
  236. hr = file.GetSize(ullLen);
  237. if(SUCCEEDED(hr))
  238. {
  239. if(ullLen > 0 && ullLen <= dwMaxFileSize)
  240. hr = fmap.MapFile(file);
  241. else if(ullLen == 0)
  242. hr = HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
  243. else
  244. hr = HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
  245. }
  246. }
  247. return hr;
  248. }
  249. HRESULT MakeSmallFilePackage(LPCTSTR lpszFileName, CAtlFile& file, CAtlFileMapping<>& fmap, WSABUF szBuf[3], const LPWSABUF pHead, const LPWSABUF pTail)
  250. {
  251. DWORD dwMaxFileSize = MAX_SMALL_FILE_SIZE - (pHead ? pHead->len : 0) - (pTail ? pTail->len : 0);
  252. ASSERT(dwMaxFileSize <= MAX_SMALL_FILE_SIZE);
  253. HRESULT hr = ReadSmallFile(lpszFileName, file, fmap, dwMaxFileSize);
  254. if(SUCCEEDED(hr))
  255. {
  256. szBuf[1].len = (ULONG)fmap.GetMappingSize();
  257. szBuf[1].buf = fmap;
  258. if(pHead) memcpy(&szBuf[0], pHead, sizeof(WSABUF));
  259. else memset(&szBuf[0], 0, sizeof(WSABUF));
  260. if(pTail) memcpy(&szBuf[2], pTail, sizeof(WSABUF));
  261. else memset(&szBuf[2], 0, sizeof(WSABUF));
  262. }
  263. return hr;
  264. }
  265. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  266. BOOL PostIocpCommand(HANDLE hIOCP, EnIocpCommand enCmd, ULONG_PTR ulParam)
  267. {
  268. return ::PostQueuedCompletionStatus(hIOCP, enCmd, ulParam, nullptr);
  269. }
  270. BOOL PostIocpExit(HANDLE hIOCP)
  271. {
  272. return PostIocpCommand(hIOCP, IOCP_CMD_EXIT, 0);
  273. }
  274. BOOL PostIocpAccept(HANDLE hIOCP)
  275. {
  276. return PostIocpCommand(hIOCP, IOCP_CMD_ACCEPT, 0);
  277. }
  278. BOOL PostIocpDisconnect(HANDLE hIOCP, CONNID dwConnID)
  279. {
  280. return PostIocpCommand(hIOCP, IOCP_CMD_DISCONNECT, dwConnID);
  281. }
  282. BOOL PostIocpSend(HANDLE hIOCP, CONNID dwConnID)
  283. {
  284. return PostIocpCommand(hIOCP, IOCP_CMD_SEND, dwConnID);
  285. }
  286. BOOL PostIocpClose(HANDLE hIOCP, CONNID dwConnID, int iErrorCode)
  287. {
  288. return PostIocpCommand(hIOCP, (EnIocpCommand)iErrorCode, dwConnID);
  289. }
  290. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  291. int SSO_SetSocketOption(SOCKET sock, int level, int name, LPVOID val, int len)
  292. {
  293. return setsockopt(sock, level, name, (CHAR*)val, len);
  294. }
  295. int SSO_GetSocketOption(SOCKET sock, int level, int name, LPVOID val, int* len)
  296. {
  297. return getsockopt(sock, level, name, (CHAR*)val, len);
  298. }
  299. int SSO_IoctlSocket(SOCKET sock, long cmd, u_long* arg)
  300. {
  301. return ioctlsocket(sock, cmd, arg);
  302. }
  303. int SSO_WSAIoctl(SOCKET sock, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned)
  304. {
  305. return ::WSAIoctl(sock, dwIoControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, nullptr, nullptr);
  306. }
  307. int SSO_UpdateAcceptContext(SOCKET soClient, SOCKET soBind)
  308. {
  309. return setsockopt(soClient, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (CHAR*)&soBind, sizeof(SOCKET));
  310. }
  311. int SSO_UpdateConnectContext(SOCKET soClient, int iOption)
  312. {
  313. return setsockopt(soClient, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, (CHAR*)&iOption, sizeof(int));
  314. }
  315. int SSO_NoDelay(SOCKET sock, BOOL bNoDelay)
  316. {
  317. return setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (CHAR*)&bNoDelay, sizeof(BOOL));
  318. }
  319. int SSO_DontLinger(SOCKET sock, BOOL bDont)
  320. {
  321. return setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (CHAR*)&bDont, sizeof(BOOL));
  322. }
  323. int SSO_Linger(SOCKET sock, USHORT l_onoff, USHORT l_linger)
  324. {
  325. linger ln = {l_onoff, l_linger};
  326. return setsockopt(sock, SOL_SOCKET, SO_LINGER, (CHAR*)&ln, sizeof(linger));
  327. }
  328. int SSO_KeepAlive(SOCKET sock, BOOL bKeepAlive)
  329. {
  330. return setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (CHAR*)&bKeepAlive, sizeof(BOOL));
  331. }
  332. int SSO_KeepAliveVals(SOCKET sock, u_long onoff, u_long time, u_long interval)
  333. {
  334. int result = NO_ERROR;
  335. tcp_keepalive in = {onoff, time, interval};
  336. DWORD dwBytes;
  337. if(::WSAIoctl (
  338. sock,
  339. SIO_KEEPALIVE_VALS,
  340. (LPVOID)&in,
  341. sizeof(in),
  342. nullptr,
  343. 0,
  344. &dwBytes,
  345. nullptr,
  346. nullptr
  347. ) == SOCKET_ERROR)
  348. {
  349. result = ::WSAGetLastError();
  350. if(result == WSAEWOULDBLOCK)
  351. result = NO_ERROR;
  352. }
  353. return result;
  354. }
  355. int SSO_RecvBuffSize(SOCKET sock, int size)
  356. {
  357. return setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (CHAR*)&size, sizeof(int));
  358. }
  359. int SSO_SendBuffSize(SOCKET sock, int size)
  360. {
  361. return setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (CHAR*)&size, sizeof(int));
  362. }
  363. int SSO_ReuseAddress(SOCKET sock, BOOL bReuse)
  364. {
  365. return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&bReuse, sizeof(BOOL));
  366. }
  367. int SSO_UDP_ConnReset(SOCKET sock, BOOL bNewBehavior)
  368. {
  369. int result = NO_ERROR;
  370. DWORD dwBytes;
  371. if(::WSAIoctl (
  372. sock,
  373. SIO_UDP_CONNRESET,
  374. (LPVOID)&bNewBehavior,
  375. sizeof(bNewBehavior),
  376. nullptr,
  377. 0,
  378. &dwBytes,
  379. nullptr,
  380. nullptr
  381. ) == SOCKET_ERROR)
  382. {
  383. result = ::WSAGetLastError();
  384. if(result == WSAEWOULDBLOCK)
  385. result = NO_ERROR;
  386. }
  387. return result;
  388. }
  389. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  390. CONNID GenerateConnectionID()
  391. {
  392. static volatile CONNID s_dwConnID = 0;
  393. CONNID dwConnID = ::InterlockedIncrement(&s_dwConnID);
  394. if(dwConnID == 0)
  395. dwConnID = ::InterlockedIncrement(&s_dwConnID);
  396. return dwConnID;
  397. }
  398. int ManualCloseSocket(SOCKET sock, int iShutdownFlag, BOOL bGraceful, BOOL bReuseAddress)
  399. {
  400. if(!bGraceful)
  401. SSO_Linger(sock, 1, 0);
  402. if(bReuseAddress)
  403. SSO_ReuseAddress(sock, bReuseAddress);
  404. if(iShutdownFlag != 0xFF)
  405. shutdown(sock, iShutdownFlag);
  406. return closesocket(sock);
  407. }
  408. int PostAccept(LPFN_ACCEPTEX pfnAcceptEx, SOCKET soListen, SOCKET soClient, TBufferObj* pBufferObj)
  409. {
  410. int result = PostAcceptNotCheck(pfnAcceptEx, soListen, soClient, pBufferObj);
  411. if(result == WSA_IO_PENDING)
  412. result = NO_ERROR;
  413. return result;
  414. }
  415. int PostAcceptNotCheck(LPFN_ACCEPTEX pfnAcceptEx, SOCKET soListen, SOCKET soClient, TBufferObj* pBufferObj)
  416. {
  417. int result = NO_ERROR;
  418. pBufferObj->client = soClient;
  419. pBufferObj->operation = SO_ACCEPT;
  420. if(!pfnAcceptEx (
  421. soListen,
  422. pBufferObj->client,
  423. pBufferObj->buff.buf,
  424. 0,
  425. sizeof(SOCKADDR_IN) + 16,
  426. sizeof(SOCKADDR_IN) + 16,
  427. nullptr,
  428. &pBufferObj->ov
  429. )
  430. )
  431. {
  432. result = ::WSAGetLastError();
  433. }
  434. return result;
  435. }
  436. int PostConnect(LPFN_CONNECTEX pfnConnectEx, SOCKET soClient, SOCKADDR_IN& soAddrIN, TBufferObj* pBufferObj)
  437. {
  438. int result = PostConnectNotCheck(pfnConnectEx, soClient, soAddrIN, pBufferObj);
  439. if(result == WSA_IO_PENDING)
  440. result = NO_ERROR;
  441. return result;
  442. }
  443. int PostConnectNotCheck(LPFN_CONNECTEX pfnConnectEx, SOCKET soClient, SOCKADDR_IN& soAddrIN, TBufferObj* pBufferObj)
  444. {
  445. int result = NO_ERROR;
  446. pBufferObj->client = soClient;
  447. pBufferObj->operation = SO_CONNECT;
  448. if(!pfnConnectEx (
  449. soClient,
  450. (SOCKADDR*)&soAddrIN,
  451. sizeof(SOCKADDR_IN),
  452. nullptr,
  453. 0,
  454. nullptr,
  455. &pBufferObj->ov
  456. )
  457. )
  458. {
  459. result = ::WSAGetLastError();
  460. }
  461. return result;
  462. }
  463. int PostSend(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
  464. {
  465. int result = PostSendNotCheck(pSocketObj, pBufferObj);
  466. if(result == WSA_IO_PENDING)
  467. result = NO_ERROR;
  468. return result;
  469. }
  470. int PostSendNotCheck(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
  471. {
  472. int result = NO_ERROR;
  473. DWORD dwBytes = 0;
  474. pBufferObj->client = pSocketObj->socket;
  475. pBufferObj->operation = SO_SEND;
  476. if(::WSASend(
  477. pBufferObj->client,
  478. &pBufferObj->buff,
  479. 1,
  480. &dwBytes,
  481. 0,
  482. &pBufferObj->ov,
  483. nullptr
  484. ) == SOCKET_ERROR)
  485. {
  486. result = ::WSAGetLastError();
  487. }
  488. return result;
  489. }
  490. int PostReceive(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
  491. {
  492. int result = PostReceiveNotCheck(pSocketObj, pBufferObj);
  493. if(result == WSA_IO_PENDING)
  494. result = NO_ERROR;
  495. return result;
  496. }
  497. int PostReceiveNotCheck(TSocketObj* pSocketObj, TBufferObj* pBufferObj)
  498. {
  499. int result = NO_ERROR;
  500. DWORD dwFlag = 0;
  501. DWORD dwBytes = 0;
  502. pBufferObj->client = pSocketObj->socket;
  503. pBufferObj->operation = SO_RECEIVE;
  504. if(::WSARecv(
  505. pBufferObj->client,
  506. &pBufferObj->buff,
  507. 1,
  508. &dwBytes,
  509. &dwFlag,
  510. &pBufferObj->ov,
  511. nullptr
  512. ) == SOCKET_ERROR)
  513. {
  514. result = ::WSAGetLastError();
  515. }
  516. return result;
  517. }
  518. int PostSendTo(SOCKET sock, TUdpBufferObj* pBufferObj)
  519. {
  520. int result = PostSendToNotCheck(sock, pBufferObj);
  521. if(result == WSA_IO_PENDING)
  522. result = NO_ERROR;
  523. return result;
  524. }
  525. int PostSendToNotCheck(SOCKET sock, TUdpBufferObj* pBufferObj)
  526. {
  527. int result = NO_ERROR;
  528. DWORD dwBytes = 0;
  529. pBufferObj->operation = SO_SEND;
  530. pBufferObj->addrLen = sizeof(SOCKADDR_IN);
  531. if(::WSASendTo (
  532. sock,
  533. &pBufferObj->buff,
  534. 1,
  535. &dwBytes,
  536. 0,
  537. (sockaddr*)&pBufferObj->remoteAddr,
  538. pBufferObj->addrLen,
  539. &pBufferObj->ov,
  540. nullptr
  541. ) == SOCKET_ERROR)
  542. {
  543. result = ::WSAGetLastError();
  544. }
  545. return result;
  546. }
  547. int PostReceiveFrom(SOCKET sock, TUdpBufferObj* pBufferObj)
  548. {
  549. int result = PostReceiveFromNotCheck(sock, pBufferObj);
  550. if(result == WSA_IO_PENDING)
  551. result = NO_ERROR;
  552. return result;
  553. }
  554. int PostReceiveFromNotCheck(SOCKET sock, TUdpBufferObj* pBufferObj)
  555. {
  556. int result = NO_ERROR;
  557. DWORD dwFlag = 0;
  558. DWORD dwBytes = 0;
  559. pBufferObj->operation = SO_RECEIVE;
  560. pBufferObj->addrLen = sizeof(SOCKADDR_IN);
  561. ::ZeroMemory(&pBufferObj->remoteAddr, pBufferObj->addrLen);
  562. if(::WSARecvFrom(
  563. sock,
  564. &pBufferObj->buff,
  565. 1,
  566. &dwBytes,
  567. &dwFlag,
  568. (sockaddr*)&pBufferObj->remoteAddr,
  569. &pBufferObj->addrLen,
  570. &pBufferObj->ov,
  571. nullptr
  572. ) == SOCKET_ERROR)
  573. {
  574. result = ::WSAGetLastError();
  575. }
  576. return result;
  577. }
  578. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  579. LPCTSTR GetSocketErrorDesc(EnSocketError enCode)
  580. {
  581. switch(enCode)
  582. {
  583. case SE_OK: return _T("SUCCESS");
  584. case SE_ILLEGAL_STATE: return _T("Illegal State");
  585. case SE_INVALID_PARAM: return _T("Invalid Parameter");
  586. case SE_SOCKET_CREATE: return _T("Create SOCKET Fail");
  587. case SE_SOCKET_BIND: return _T("Bind SOCKET Fail");
  588. case SE_SOCKET_PREPARE: return _T("Prepare SOCKET Fail");
  589. case SE_SOCKET_LISTEN: return _T("Listen SOCKET Fail");
  590. case SE_CP_CREATE: return _T("Create IOCP Fail");
  591. case SE_WORKER_THREAD_CREATE: return _T("Create Worker Thread Fail");
  592. case SE_DETECT_THREAD_CREATE: return _T("Create Detector Thread Fail");
  593. case SE_SOCKE_ATTACH_TO_CP: return _T("Attach SOCKET to IOCP Fail");
  594. case SE_CONNECT_SERVER: return _T("Connect to Server Fail");
  595. case SE_NETWORK: return _T("Network Error");
  596. case SE_DATA_PROC: return _T("Process Data Error");
  597. case SE_DATA_SEND: return _T("Send Data Fail");
  598. case SE_SSL_ENV_NOT_READY: return _T("SSL environment not ready");
  599. default: ASSERT(FALSE); return _T("UNKNOWN ERROR");
  600. }
  601. }
  602. DWORD GetHPSocketVersion()
  603. {
  604. static DWORD s_dwVersion = (HP_VERSION_MAJOR << 24) | (HP_VERSION_MINOR << 16) | (HP_VERSION_REVISE << 8) | HP_VERSION_BUILD;
  605. return s_dwVersion;
  606. }