SocketHandle.cpp 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630
  1. #include "stdafx.h"
  2. #ifdef WIN32
  3. #include <stdlib.h>
  4. #ifndef UNDER_CE
  5. #include <crtdbg.h>
  6. #endif
  7. #include <strsafe.h>
  8. #endif
  9. #include "SocketHandle.h"
  10. #include <MSTcpIP.h>
  11. #ifndef BUFFER_SIZE
  12. #define BUFFER_SIZE 64*1024
  13. #endif
  14. #ifndef SOCKHANDLE_TTL
  15. #define SOCKHANDLE_TTL 5
  16. #endif
  17. #ifndef SOCKHANDLE_HOPS
  18. #define SOCKHANDLE_HOPS 10
  19. #endif
  20. #define HOSTNAME_SIZE MAX_PATH
  21. #define STRING_LENGTH 40
  22. #if !defined(PLATFORM_HAS_INETFUNC)
  23. const char *inet_ntop(int af, const void *src, char *dst, size_t cnt);
  24. int inet_pton(int af, const char *src, void *dst);
  25. #endif
  26. #ifdef WIN32
  27. #ifndef UNDER_CE
  28. #pragma comment(lib, "ws2_32.lib")
  29. #else
  30. #pragma comment(lib, "Ws2.lib")
  31. #endif
  32. #endif
  33. #if 1
  34. typedef struct STcpKeepAlive2
  35. {
  36. DWORD onoff;
  37. DWORD keepalivetime;
  38. DWORD keepaliveinterval;
  39. }TCP_KEEP_ALIVE2;
  40. /************************************************************************/
  41. /* 函数:SetKeepLive[2/29/2016 IT];
  42. /* 描述:设置TCP连接鲜活时间;
  43. /* 参数:;
  44. /* [IN] Socket:要设置的客户端SOCKET;
  45. /* 返回:设置成功返回TRUE;
  46. /* 注意:;
  47. /* 示例:;
  48. /*
  49. /* 修改:;
  50. /* 日期:;
  51. /* 内容:;
  52. /************************************************************************/
  53. BOOL SetKeepLive(IN SOCKET &Socket)
  54. {
  55. const BYTE chOpt = 1; // True;
  56. // Set KeepAlive 开启保活机制, 防止服务端产生死连接;
  57. if (setsockopt(Socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&chOpt, sizeof(chOpt)) == SOCKET_ERROR)
  58. {
  59. printf("设置客户端鲜活机制失败1\n\n");
  60. return FALSE;
  61. }
  62. // 设置超时详细信息;
  63. BYTE byRet[5] = {0};
  64. TCP_KEEP_ALIVE2 klive;
  65. klive.onoff = 1; // 启用保活;
  66. klive.keepalivetime = 1000 * 15; // 3分钟超时 Keep Alive;
  67. klive.keepaliveinterval = 1000 * 5; // 重试间隔为5秒 Resend if No-Reply;
  68. INT nResult =
  69. WSAIoctl
  70. (
  71. Socket,
  72. SIO_KEEPALIVE_VALS,
  73. &klive,
  74. sizeof(TCP_KEEP_ALIVE2),
  75. NULL,
  76. 0,
  77. (unsigned long *)&byRet,
  78. 0,
  79. NULL
  80. );
  81. if ( nResult == SOCKET_ERROR )
  82. {
  83. printf("设置客户端鲜活机制失败2\n\n");
  84. return FALSE;
  85. }
  86. return TRUE;
  87. }
  88. #endif
  89. CSocketHandle::CSocketHandle(): m_hSocket(INVALID_SOCKET)
  90. {
  91. }
  92. CSocketHandle::~CSocketHandle()
  93. {
  94. Close();
  95. }
  96. bool CSocketHandle::IsOpen() const
  97. {
  98. return ( INVALID_SOCKET != m_hSocket );
  99. }
  100. SOCKET CSocketHandle::GetSocket() const
  101. {
  102. return m_hSocket;
  103. }
  104. /************************************************************************/
  105. /* 函数:GetSocketType[2/29/2016 IT];
  106. /* 描述:获取套接字类型;
  107. /* 参数:;
  108. /* 返回:返回-1表示不是一个有效的套接字;
  109. /* 注意:;
  110. /* 示例:;
  111. /*
  112. /* 修改:;
  113. /* 日期:;
  114. /* 内容:;
  115. /************************************************************************/
  116. int CSocketHandle::GetSocketType() const
  117. {
  118. int type = -1;
  119. if ( INVALID_SOCKET != m_hSocket ) {
  120. socklen_t optlen = sizeof(int);
  121. if ( getsockopt(GetSocket(), SOL_SOCKET, SO_TYPE, reinterpret_cast<char*>(&type),&optlen) == SOCKET_ERROR)
  122. {
  123. SetLastError( WSAGetLastError() );
  124. }
  125. }
  126. return type;
  127. }
  128. /************************************************************************/
  129. /* 函数:Attach[2/29/2016 IT];
  130. /* 描述:附加一个SOCKET句柄,使用Detach函数或Close函数来释放句柄;
  131. /* 参数:;
  132. /* [IN] sock:要附加到类中的套接字句柄;
  133. /* 返回:成功返回TRUE;
  134. /* 注意:函数有可能失败,当要附加的套接字是一个无效值或该值已在使用时;
  135. /* 示例:;
  136. /*
  137. /* 修改:;
  138. /* 日期:;
  139. /* 内容:;
  140. /************************************************************************/
  141. bool CSocketHandle::Attach(IN SOCKET sock)
  142. {
  143. if ( INVALID_SOCKET == m_hSocket )
  144. {
  145. m_hSocket = sock;
  146. return true;
  147. }
  148. return false;
  149. }
  150. /************************************************************************/
  151. /* 函数:Detach[2/29/2016 IT];
  152. /* 描述:把套接字从类对象中分离出来;
  153. /* 参数:无;
  154. /* 返回:返回前面附加的套接字句柄或INVALID_SOCKET;
  155. /* 注意:;
  156. /* 示例:;
  157. /*
  158. /* 修改:;
  159. /* 日期:;
  160. /* 内容:;
  161. /************************************************************************/
  162. SOCKET CSocketHandle::Detach()
  163. {
  164. SOCKET sock = m_hSocket;
  165. ::InterlockedExchange(reinterpret_cast<long*>(&m_hSocket), INVALID_SOCKET);
  166. return sock;
  167. }
  168. /************************************************************************/
  169. /* 函数:GetSockName[2/29/2016 IT];
  170. /* 描述:获取套接字名(本地地址);
  171. /* 参数:;
  172. /* [OUT] saddr_in:连接成功时返回的当前本地地址和端口号;
  173. /* 返回:成功返回TRUE;
  174. /* 注意:使用前必须调用InitLibrary函数;
  175. /* 示例:;
  176. /*
  177. /* 修改:;
  178. /* 日期:;
  179. /* 内容:;
  180. /************************************************************************/
  181. bool CSocketHandle::GetSockName(OUT SockAddrIn& saddr_in) const
  182. {
  183. _ASSERTE( IsOpen() );
  184. if (IsOpen()) {
  185. socklen_t namelen = (socklen_t)saddr_in.Size();
  186. if (SOCKET_ERROR != getsockname(GetSocket(), saddr_in, &namelen))
  187. {
  188. return true;
  189. }
  190. SetLastError( WSAGetLastError() );
  191. }
  192. return false;
  193. }
  194. /************************************************************************/
  195. /* 函数:GetPeerName[2/29/2016 IT];
  196. /* 描述:获取点对点的套接接名(获取Peer地址);;
  197. /* 参数:;
  198. /* [OUT] saddr_in: peer address and port (use only with TCP or client mode UDP);
  199. /* 返回:成功返回TRUE;
  200. /* 注意:使用前必须调用InitLibrary函数;
  201. /* 示例:;
  202. /*
  203. /* 修改:;
  204. /* 日期:;
  205. /* 内容:;
  206. /************************************************************************/
  207. bool CSocketHandle::GetPeerName(OUT SockAddrIn& saddr_in) const
  208. {
  209. _ASSERTE( IsOpen() );
  210. if (IsOpen()) {
  211. socklen_t namelen = (socklen_t)saddr_in.Size();
  212. if (SOCKET_ERROR != getpeername(GetSocket(), saddr_in, &namelen))
  213. {
  214. return true;
  215. }
  216. SetLastError( WSAGetLastError() );
  217. }
  218. return false;
  219. }
  220. /************************************************************************/
  221. /* 函数:Close[2/29/2016 IT];
  222. /* 描述:关闭套接字;
  223. /* 参数:;
  224. /* 返回:void;
  225. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen;
  226. /* 示例:;
  227. /*
  228. /* 修改:;
  229. /* 日期:;
  230. /* 内容:;
  231. /************************************************************************/
  232. void CSocketHandle::Close()
  233. {
  234. if ( IsOpen() )
  235. {
  236. ShutdownConnection(static_cast<SOCKET>(::InterlockedExchange((LONG*)&m_hSocket, INVALID_SOCKET)));
  237. }
  238. }
  239. /************************************************************************/
  240. /* 函数:AddMembership[2/29/2016 IT];
  241. /* 描述:添加多播地址;
  242. /* 参数:;
  243. /* [IN] pszIPAddr:多播IP组;
  244. /* [IN] pszNIC:IP地址接口(多张网卡时,某一网卡序列号);
  245. /* 返回:成功返回TRUE;
  246. /* 注意:关联InitLibrary函数;
  247. /* 示例:;
  248. /*
  249. /* 修改:;
  250. /* 日期:;
  251. /* 内容:;
  252. /************************************************************************/
  253. bool CSocketHandle::AddMembership(IN LPCTSTR pszIPAddr, IN LPCTSTR pszNIC)
  254. {
  255. _ASSERTE( IsOpen() );
  256. if ( IsOpen() )
  257. {
  258. int nType = 0;
  259. socklen_t nOptLen = sizeof(int);
  260. if ( SOCKET_ERROR != getsockopt(m_hSocket, SOL_SOCKET, SO_TYPE, (char*)&nType, &nOptLen))
  261. {
  262. if ( nType == SOCK_DGRAM )
  263. {
  264. // Setup interface for multicast traffic
  265. SockAddrIn mcastAddr;
  266. if (GetAddressInfo(pszIPAddr, NULL, AF_UNSPEC, mcastAddr))
  267. {
  268. SockAddrIn interfAddr;
  269. GetAddressInfo(pszNIC, NULL, mcastAddr.ss_family, interfAddr);
  270. if ( mcastAddr.ss_family == AF_INET )
  271. {
  272. int nTTL = SOCKHANDLE_TTL;
  273. if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&nTTL, sizeof(nTTL)))
  274. {
  275. ULONG ulNIC = interfAddr.GetIPAddr();
  276. if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IP, IP_MULTICAST_IF,(char *) &ulNIC, sizeof(ulNIC)))
  277. {
  278. ip_mreq mreq = { 0 };
  279. mreq.imr_multiaddr.s_addr = mcastAddr.GetIPAddr();
  280. mreq.imr_interface.s_addr = ulNIC;
  281. if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)))
  282. {
  283. return true;
  284. }
  285. }
  286. }
  287. }
  288. else if ( mcastAddr.ss_family == AF_INET6 )
  289. {
  290. int nTTL = SOCKHANDLE_HOPS;
  291. if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&nTTL, sizeof(nTTL)))
  292. {
  293. ipv6_mreq mreq6 = { 0 };
  294. IN6_ADDR mcin6 = ((sockaddr_in6*)&mcastAddr)->sin6_addr;
  295. memcpy(&(mreq6.ipv6mr_multiaddr), &mcin6, sizeof(IN6_ADDR));
  296. if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char*)&mreq6, sizeof(mreq6)))
  297. {
  298. return true;
  299. }
  300. }
  301. }
  302. else
  303. {
  304. // invalid socket option
  305. WSASetLastError(WSAENOPROTOOPT);
  306. }
  307. }
  308. }
  309. else
  310. {
  311. // invalid socket option
  312. WSASetLastError(WSAENOPROTOOPT);
  313. }
  314. }
  315. SetLastError( WSAGetLastError() );
  316. }
  317. return false;
  318. }
  319. /************************************************************************/
  320. /* 函数:DropMembership[2/29/2016 IT];
  321. /* 描述:移除多播地址;
  322. /* 参数:;
  323. /* [IN] pszIPAddr:多播IP组;
  324. /* [IN] pszNIC:IP地址接口(多张网卡时,某一网卡序列号);
  325. /* 返回:成功返回TRUE;
  326. /* 注意:关联InitLibrary函数;
  327. /* 示例:;
  328. /*
  329. /* 修改:;
  330. /* 日期:;
  331. /* 内容:;
  332. /************************************************************************/
  333. bool CSocketHandle::DropMembership(LPCTSTR pszIPAddr, LPCTSTR pszNIC)
  334. {
  335. _ASSERTE( IsOpen() );
  336. if ( IsOpen() )
  337. {
  338. int nType = 0;
  339. socklen_t nOptLen = sizeof(int);
  340. if ( SOCKET_ERROR != getsockopt(m_hSocket, SOL_SOCKET, SO_TYPE, (char*)&nType, &nOptLen))
  341. {
  342. if ( nType == SOCK_DGRAM )
  343. {
  344. SockAddrIn mcastAddr;
  345. if (GetAddressInfo(pszIPAddr, NULL, AF_UNSPEC, mcastAddr))
  346. {
  347. SockAddrIn interfAddr;
  348. GetAddressInfo(pszNIC, NULL, mcastAddr.ss_family, interfAddr);
  349. if ( mcastAddr.ss_family == AF_INET )
  350. {
  351. ip_mreq mreq;
  352. mreq.imr_multiaddr.s_addr = mcastAddr.GetIPAddr();
  353. mreq.imr_interface.s_addr = interfAddr.GetIPAddr();;
  354. if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)))
  355. {
  356. return true;
  357. }
  358. }
  359. else if ( mcastAddr.ss_family == AF_INET6 )
  360. {
  361. ipv6_mreq mreq6 = { 0 };
  362. IN6_ADDR mcin6 = ((sockaddr_in6*)&mcastAddr)->sin6_addr;
  363. memcpy(&(mreq6.ipv6mr_multiaddr), &mcin6, sizeof(IN6_ADDR));
  364. if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (const char*)&mreq6, sizeof(mreq6)))
  365. {
  366. return true;
  367. }
  368. }
  369. else
  370. {
  371. // invalid socket option
  372. WSASetLastError(WSAENOPROTOOPT);
  373. }
  374. }
  375. }
  376. else
  377. {
  378. // invalid socket option
  379. WSASetLastError(WSAENOPROTOOPT);
  380. }
  381. }
  382. SetLastError( WSAGetLastError() );
  383. }
  384. return false;
  385. }
  386. /************************************************************************/
  387. /* 函数:CreateSocket[2/29/2016 IT];
  388. /* 描述:创建服务端套接字;
  389. /* 参数:;
  390. /* [IN] pszHostName:主机名或网卡适配器地址;
  391. /* [IN] pszServiceName:网络服务名或者IP端口号;
  392. /* [IN] nFamily:要用的地址协议簇类型(IPV4或IPV6);
  393. /* [IN] nType:要创建的套接字类型(SOCK_STREAM 或 SOCK_DGRAM);
  394. /* [IN] uOptions:附加选项(SO_BROADCAST,SO_REUSEADDR) ;
  395. /* 返回:成功返回TRUE;
  396. /* 注意:使用WSAGetLastError()函数获取最后的错误,关联函数InitLibrary, ConnectTo, IsOpen;
  397. /* 示例:;
  398. /*
  399. /* 修改:;
  400. /* 日期:;
  401. /* 内容:;
  402. /************************************************************************/
  403. bool CSocketHandle::CreateSocket(IN LPCTSTR pszHostName, IN LPCTSTR pszServiceName, IN int nFamily, IN int nType, IN UINT uOptions /* = 0 */)
  404. {
  405. // Socket is already opened
  406. if ( IsOpen() ) {
  407. SetLastError(ERROR_ACCESS_DENIED);
  408. return false;
  409. }
  410. // Create a Socket that is bound to a specific service provider
  411. // nFamily: (AF_INET, AF_INET6)
  412. // nType: (SOCK_STREAM, SOCK_DGRAM)
  413. #ifdef SOCKHANDLE_USE_OVERLAPPED
  414. SOCKET sock = WSASocket(nFamily, nType, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
  415. #else
  416. SOCKET sock = socket(nFamily, nType, IPPROTO_IP);
  417. #endif
  418. if (INVALID_SOCKET != sock)
  419. {
  420. if (uOptions & SO_REUSEADDR)
  421. {
  422. // Inform Windows Sockets provider that a bind on a socket should not be disallowed
  423. // because the desired address is already in use by another socket
  424. BOOL optval = TRUE;
  425. if ( SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof( BOOL ) ) )
  426. {
  427. SetLastError( WSAGetLastError() );
  428. closesocket( sock );
  429. return false;
  430. }
  431. }
  432. if (nType == SOCK_DGRAM)
  433. {
  434. if ((uOptions & SO_BROADCAST) && (nFamily == AF_INET))
  435. {
  436. // Inform Windows Sockets provider that broadcast messages are allowed
  437. BOOL optval = TRUE;
  438. if ( SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (char *) &optval, sizeof( BOOL ) ) )
  439. {
  440. SetLastError( WSAGetLastError() );
  441. closesocket( sock );
  442. return false;
  443. }
  444. }
  445. #ifdef SOCKHANDLE_CONFIGBUF
  446. // configure buffer size
  447. socklen_t rcvbuf = BUFFER_SIZE;
  448. if ( SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_RCVBUF, (char *) &rcvbuf, sizeof( int ) ) )
  449. {
  450. SetLastError( WSAGetLastError() );
  451. closesocket( sock );
  452. return false;
  453. }
  454. #endif
  455. }
  456. // Associate a local address with the socket
  457. SockAddrIn sockAddr;
  458. sockAddr.CreateFrom(pszHostName, pszServiceName, nFamily);
  459. if ( SOCKET_ERROR == bind(sock, sockAddr, (int)sockAddr.Size()))
  460. {
  461. SetLastError( WSAGetLastError() );
  462. closesocket( sock );
  463. return false;
  464. }
  465. // Listen to the socket, only valid for connection socket (TCP)
  466. if (SOCK_STREAM == nType)
  467. {
  468. if ( SOCKET_ERROR == listen(sock, SOMAXCONN))
  469. {
  470. SetLastError( WSAGetLastError() );
  471. closesocket( sock );
  472. return false;
  473. }
  474. }
  475. // Success, now we may save this socket
  476. m_hSocket = sock;
  477. }
  478. return (INVALID_SOCKET != sock);
  479. }
  480. /************************************************************************/
  481. /* 函数:ConnectTo[2/29/2016 IT];
  482. /* 描述:客户端连接服务端;
  483. /* 参数:;
  484. /* [IN] pszHostName:Hostname or NIC address;
  485. /* [IN] pszRemote:Remote network address;
  486. /* [IN] pszServiceName:Network service name or port number;
  487. /* [IN] nFamily:address family to use (AF_INET, AF_INET6);
  488. /* [IN] nType:type of socket to create (SOCK_STREAM, SOCK_DGRAM);
  489. /* 返回:return true if successful, otherwise false (call WSAGetLastError() to retrieve latest error);
  490. /* 注意:关联函数InitLibrary, CreateSocket, IsOpen;
  491. /* 示例:;
  492. /*
  493. /* 修改:;
  494. /* 日期:;
  495. /* 内容:;
  496. /************************************************************************/
  497. bool CSocketHandle::ConnectTo(IN LPCTSTR pszHostName, IN LPCTSTR pszRemote, IN LPCTSTR pszServiceName, IN int nFamily, IN int nType)
  498. {
  499. // Socket is already opened
  500. if ( IsOpen() ) {
  501. SetLastError(ERROR_ACCESS_DENIED);
  502. return false;
  503. }
  504. // Create a Socket that is bound to a specific service provider
  505. // nFamily: (AF_INET, AF_INET6)
  506. // nType: (SOCK_STREAM, SOCK_DGRAM)
  507. #ifdef SOCKHANDLE_USE_OVERLAPPED
  508. SOCKET sock = WSASocket(nFamily, nType, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
  509. #else
  510. SOCKET sock = socket(nFamily, nType, IPPROTO_IP);
  511. #endif
  512. if (INVALID_SOCKET != sock)
  513. {
  514. // Associate a local address with the socket but let provider assign a port number
  515. SockAddrIn sockAddr;
  516. if (false == sockAddr.CreateFrom(pszHostName, TEXT("0"), nFamily))
  517. {
  518. SetLastError( WSAGetLastError() );
  519. closesocket( sock );
  520. return false;
  521. }
  522. if ( SOCKET_ERROR == bind(sock, sockAddr, (int)sockAddr.Size()))
  523. {
  524. SetLastError( WSAGetLastError() );
  525. closesocket( sock );
  526. return false;
  527. }
  528. #ifdef SOCKHANDLE_CONFIGBUF
  529. if (nType == SOCK_DGRAM)
  530. {
  531. // configure buffer size
  532. socklen_t rcvbuf = BUFFER_SIZE;
  533. if ( SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_RCVBUF, (char *) &rcvbuf, sizeof( int ) ) )
  534. {
  535. SetLastError( WSAGetLastError() );
  536. closesocket( sock );
  537. return false;
  538. }
  539. }
  540. #endif
  541. // Now get destination address & port
  542. sockAddr.CreateFrom( pszRemote, pszServiceName, nFamily );
  543. // try to connect - if fail, server not ready
  544. if (SOCKET_ERROR == connect( sock, sockAddr, (int)sockAddr.Size()))
  545. {
  546. SetLastError( WSAGetLastError() );
  547. closesocket( sock );
  548. return false;
  549. }
  550. // Success, now we may save this socket
  551. m_hSocket = sock;
  552. }
  553. return (INVALID_SOCKET != sock);
  554. }
  555. /************************************************************************/
  556. /* 函数:Read[2/29/2016 IT];
  557. /* 描述:从套接字中读取内容;
  558. /* 参数:;
  559. /* [OUT] lpBuffer:Buffer to receive data;
  560. /* [IN] dwSize:Size of buffer in bytes;
  561. /* [IN] lpAddrIn:Peer address for UDP - this must be NULL for TCP;
  562. /* [IN] dwTimeout:Read timeout in milliseconds;
  563. /* 返回:return number of bytes read or (-1L) if fail;
  564. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, Write, WriteEx;
  565. /* 示例:;
  566. /*
  567. /* 修改:;
  568. /* 日期:;
  569. /* 内容:;
  570. /************************************************************************/
  571. DWORD CSocketHandle::Read(OUT LPBYTE lpBuffer, IN DWORD dwSize, IN LPSOCKADDR lpAddrIn /* = NULL */, IN DWORD dwTimeout /* = INFINITE */)
  572. {
  573. _ASSERTE( IsOpen() );
  574. _ASSERTE( lpBuffer != NULL );
  575. if (!IsOpen() || lpBuffer == NULL || dwSize < 1L)
  576. return (DWORD)-1L;
  577. fd_set fdRead = { 0 };
  578. TIMEVAL stTime;
  579. TIMEVAL *pstTime = NULL;
  580. if ( INFINITE != dwTimeout ) {
  581. stTime.tv_sec = dwTimeout/1000;
  582. stTime.tv_usec = (dwTimeout%1000)*1000;
  583. pstTime = &stTime;
  584. }
  585. SOCKET s = GetSocket();
  586. // Set Descriptor
  587. FD_SET( s, &fdRead );
  588. // Select function set read timeout
  589. DWORD dwBytesRead = 0L;
  590. int res = 1;
  591. if ( pstTime != NULL )
  592. res = select((int)s, &fdRead, NULL, NULL, pstTime );
  593. if ( res > 0)
  594. {
  595. if (lpAddrIn)
  596. {
  597. // UDP
  598. socklen_t fromlen = sizeof(SOCKADDR_STORAGE);
  599. res = recvfrom(s, reinterpret_cast<LPSTR>(lpBuffer), dwSize, 0, lpAddrIn, &fromlen);
  600. }
  601. else
  602. {
  603. // TCP
  604. res = recv(s, reinterpret_cast<LPSTR>(lpBuffer), dwSize, 0);
  605. }
  606. if ( res == 0 ) {
  607. WSASetLastError(WSAECONNRESET);
  608. res = SOCKET_ERROR;
  609. }
  610. }
  611. if ( res == SOCKET_ERROR )
  612. {
  613. SetLastError( WSAGetLastError() );
  614. }
  615. dwBytesRead = (DWORD)((res >= 0)?(res) : (-1));
  616. return dwBytesRead;
  617. }
  618. #ifdef WIN32
  619. /************************************************************************/
  620. /* 函数:ReadEx[2/29/2016 IT];
  621. /* 描述:从套接字读取内容,异步模式(asynchronous mode);
  622. /* 参数:;
  623. /* [OUT] lpBuffer:Buffer to receive data;
  624. /* [IN] dwSize:Size of buffer in bytes;
  625. /* [IN] lpAddrIn:SockAddrIn for UDP - this must be NULL for TCP;
  626. /* [IN] lpOverlapped:Windows Overlapped structure (required);
  627. /* [IN] lpCompletionRoutine:Winsock Completion routine (required);
  628. /* 返回:return number of bytes read, overlapped operation is pending or (-1L) if fail;
  629. /* 注意:关联函数 InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, Write, WriteEx, IOControl, GetTransferOverlappedResult;
  630. /* 示例:;
  631. /*
  632. /* 修改:;
  633. /* 日期:;
  634. /* 内容:;
  635. /************************************************************************/
  636. DWORD CSocketHandle::ReadEx(OUT LPBYTE lpBuffer, IN DWORD dwSize, IN LPSOCKADDR lpAddrIn, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSACOMPLETIONROUTINE lpCompletionRoutine)
  637. {
  638. _ASSERTE( IsOpen() );
  639. _ASSERTE( lpBuffer != NULL );
  640. if (!IsOpen() || lpBuffer == NULL || dwSize < 1L)
  641. return (DWORD)-1L;
  642. SOCKET s = GetSocket();
  643. // Send message to peer
  644. WSABUF wsabuf;
  645. wsabuf.buf = (char FAR*)lpBuffer;
  646. wsabuf.len = dwSize;
  647. // Select function set read timeout
  648. DWORD dwBytesRead = 0L;
  649. DWORD dwFlags = 0L;
  650. int res = 0;
  651. if (lpAddrIn)
  652. {
  653. // UDP
  654. socklen_t fromlen = sizeof(SOCKADDR_STORAGE);
  655. res = WSARecvFrom( s, &wsabuf, 1, &dwBytesRead, &dwFlags, lpAddrIn, &fromlen, lpOverlapped, lpCompletionRoutine);
  656. }
  657. else
  658. {
  659. // TCP
  660. res = WSARecv( s, &wsabuf, 1, &dwBytesRead, &dwFlags, lpOverlapped, lpCompletionRoutine);
  661. }
  662. if ( res == SOCKET_ERROR )
  663. {
  664. res = WSAGetLastError();
  665. if ( res != WSA_IO_PENDING )
  666. {
  667. dwBytesRead = (DWORD)-1L;
  668. SetLastError( res );
  669. }
  670. }
  671. return dwBytesRead;
  672. }
  673. #endif
  674. /************************************************************************/
  675. /* 函数:Write[2/29/2016 IT];
  676. /* 描述:向目标套接字发送内容;
  677. /* 参数:;
  678. /* [IN] lpBuffer:Buffer to send;
  679. /* [IN] dwCount:Number of bytes to send;
  680. /* [IN] lpAddrIn:Peer address for UDP - this must be NULL for TCP;
  681. /* [IN] dwTimeout:Write timeout in milliseconds;
  682. /* 返回:return number of bytes sent or (-1L) if fail;
  683. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, ReadEx, WriteEx;
  684. /* 示例:;
  685. /*
  686. /* 修改:;
  687. /* 日期:;
  688. /* 内容:;
  689. /************************************************************************/
  690. DWORD CSocketHandle::Write(IN const LPBYTE lpBuffer, IN DWORD dwCount, IN const LPSOCKADDR lpAddrIn /* = NULL */, IN DWORD dwTimeout /* = INFINITE */)
  691. {
  692. _ASSERTE( IsOpen() );
  693. _ASSERTE( NULL != lpBuffer );
  694. // validate params
  695. if (!IsOpen() || NULL == lpBuffer)
  696. return (DWORD)-1L;
  697. fd_set fdWrite = { 0 };
  698. TIMEVAL stTime;
  699. TIMEVAL *pstTime = NULL;
  700. if ( INFINITE != dwTimeout ) {
  701. stTime.tv_sec = dwTimeout/1000;
  702. stTime.tv_usec = (dwTimeout%1000)*1000;
  703. pstTime = &stTime;
  704. }
  705. SOCKET s = GetSocket();
  706. // Set Descriptor
  707. FD_SET( s, &fdWrite );
  708. // Select function set write timeout
  709. DWORD dwBytesWritten = 0L;
  710. int res = 1;
  711. if ( pstTime != NULL )
  712. {
  713. res = select((int)s, NULL, &fdWrite, NULL, pstTime );
  714. }
  715. if ( res > 0)
  716. {
  717. // Send message to peer
  718. if (lpAddrIn)
  719. {
  720. // UDP
  721. res = sendto( s, reinterpret_cast<LPCSTR>(lpBuffer), dwCount, 0, lpAddrIn, sizeof(SOCKADDR_STORAGE));
  722. }
  723. else
  724. {
  725. // TCP
  726. res = send( s, reinterpret_cast<LPCSTR>(lpBuffer), dwCount, 0);
  727. }
  728. }
  729. if ( res == SOCKET_ERROR )
  730. {
  731. SetLastError( WSAGetLastError() );
  732. }
  733. dwBytesWritten = (DWORD)((res >= 0)?(res) : (-1));
  734. return dwBytesWritten;
  735. }
  736. #ifdef WIN32
  737. /************************************************************************/
  738. /* 函数:WriteEx[2/29/2016 IT];
  739. /* 描述:向目标套接字发送内容,异步模式(asynchronous mode);
  740. /* 参数:;
  741. /* [IN] lpBuffer:Buffer to send;
  742. /* [IN] dwCount:Number of bytes to send;
  743. /* [IN] lpAddrIn:SockAddrIn for UDP - this must be NULL for TCP;
  744. /* [IN] lpOverlapped:Windows Overlapped structure (required);
  745. /* [IN] lpCompletionRoutine:Winsock Completion routine (required);
  746. /* 返回:return number of bytes read, overlapped operation is pending or (-1L) if fail;
  747. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, ReadEx, Write, IOControl, GetTransferOverlappedResult;
  748. /* 示例:;
  749. /*
  750. /* 修改:;
  751. /* 日期:;
  752. /* 内容:;
  753. /************************************************************************/
  754. DWORD CSocketHandle::WriteEx(IN const LPBYTE lpBuffer, IN DWORD dwCount, IN const LPSOCKADDR lpAddrIn, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSACOMPLETIONROUTINE lpCompletionRoutine)
  755. {
  756. _ASSERTE( IsOpen() );
  757. _ASSERTE( NULL != lpBuffer );
  758. // validate params
  759. if (!IsOpen() || NULL == lpBuffer)
  760. return (DWORD)-1L;
  761. SOCKET s = GetSocket();
  762. // Select function set write timeout
  763. DWORD dwBytesWritten = 0L;
  764. int res = 0;
  765. // Send message to peer
  766. WSABUF wsabuf;
  767. wsabuf.buf = (char FAR*) lpBuffer;
  768. wsabuf.len = dwCount;
  769. if (lpAddrIn)
  770. {
  771. // UDP
  772. res = WSASendTo( s, &wsabuf, 1, &dwBytesWritten, 0, lpAddrIn, sizeof(SOCKADDR_STORAGE),
  773. lpOverlapped, lpCompletionRoutine);
  774. }
  775. else // TCP
  776. res = WSASend( s, &wsabuf, 1, &dwBytesWritten, 0, lpOverlapped, lpCompletionRoutine);
  777. if ( res == SOCKET_ERROR )
  778. {
  779. res = WSAGetLastError();
  780. if ( res != WSA_IO_PENDING )
  781. {
  782. dwBytesWritten = (DWORD)-1L;
  783. SetLastError( res );
  784. }
  785. }
  786. return dwBytesWritten;
  787. }
  788. #endif
  789. #ifdef WIN32
  790. /************************************************************************/
  791. /* 函数:IOControl[2/29/2016 IT];
  792. /* 描述:Control the mode of a socket (asynchronous mode);
  793. /* 参数:;
  794. /* [IN] dwIoCode:Control code of operation to perform;
  795. /* [IN] lpInBuffer:Pointer to the input buffer;
  796. /* [IN] cbInBuffer:Size of the input buffer, in bytes;
  797. /* [IN] lpOutBuffer:Pointer to the output buffer;
  798. /* [IN] cbOutBuffer:Size of the output buffer, in bytes;
  799. /* [IN] lpcbBytesReturned:Pointer to actual number of bytes of output;
  800. /* [IN] lpOverlapped:Winsock Overlapped structure;
  801. /* [IN] lpCompletionRoutine:Winsock Completion routine;
  802. /* 返回:return true if successful, otherwise false (call WSAGetLastError() to retrieve latest error);
  803. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, WriteEx, GetTransferOverlappedResult;
  804. /* 示例:;
  805. /*
  806. /* 修改:;
  807. /* 日期:;
  808. /* 内容:;
  809. /************************************************************************/
  810. bool CSocketHandle::IOControl(
  811. IN DWORD dwIoCode,
  812. IN LPBYTE lpInBuffer,
  813. IN DWORD cbInBuffer,
  814. IN LPBYTE lpOutBuffer,
  815. IN DWORD cbOutBuffer,
  816. IN LPDWORD lpcbBytesReturned,
  817. IN LPWSAOVERLAPPED lpOverlapped,
  818. IN LPWSACOMPLETIONROUTINE lpCompletionRoutine )
  819. {
  820. _ASSERTE( IsOpen() );
  821. // validate params
  822. if ( !IsOpen() ) {
  823. SetLastError(ERROR_INVALID_HANDLE);
  824. return false;
  825. }
  826. int res;
  827. SOCKET s = GetSocket();
  828. res = WSAIoctl(s, dwIoCode, lpInBuffer, cbInBuffer, lpOutBuffer, cbOutBuffer,
  829. lpcbBytesReturned, lpOverlapped, lpCompletionRoutine);
  830. if ( res == SOCKET_ERROR )
  831. {
  832. SetLastError( WSAGetLastError() );
  833. }
  834. return ( res != SOCKET_ERROR );
  835. }
  836. /************************************************************************/
  837. /* 函数:GetTransferOverlappedResult[2/29/2016 IT];
  838. /* 描述:Get Overlapped result (asynchronous mode);
  839. /* 参数:;
  840. /* [IN] lpOverlapped:Windows Overlapped structure (required);
  841. /* [IN] lpcbTransfer:Pointer to get number of bytes transferred;
  842. /* [IN] bWait:Force wait for overlapped operation to complete;
  843. /* [IN] lpdwFlags:Optional flags (see MSDN on WSARecv API);
  844. /* [OUT] :;
  845. /* [IN/OUT] :;
  846. /* 返回:成功返回TRUE;
  847. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, WriteEx, IOControl;
  848. /* 示例:;
  849. /*
  850. /* 修改:;
  851. /* 日期:;
  852. /* 内容:;
  853. /************************************************************************/
  854. bool CSocketHandle::GetTransferOverlappedResult(IN LPWSAOVERLAPPED lpOverlapped, IN LPDWORD lpcbTransfer, IN bool bWait /* = true */, IN LPDWORD lpdwFlags /* = 0 */)
  855. {
  856. _ASSERTE( IsOpen() );
  857. _ASSERTE( NULL != lpOverlapped );
  858. // validate params
  859. if (!IsOpen() || NULL == lpOverlapped) {
  860. SetLastError(ERROR_INVALID_HANDLE);
  861. return false;
  862. }
  863. SOCKET s = GetSocket();
  864. DWORD dwFlags = 0;
  865. if ( lpdwFlags == NULL )
  866. lpdwFlags = &dwFlags;
  867. BOOL bRet = WSAGetOverlappedResult( s, lpOverlapped, lpcbTransfer, bWait, lpdwFlags );
  868. if ( !bRet )
  869. {
  870. SetLastError( WSAGetLastError() );
  871. }
  872. return (bRet != FALSE);
  873. }
  874. #endif
  875. ///////////////////////////////////////////////////////////////////////////////
  876. // Utility functions
  877. /************************************************************************/
  878. /* 函数:InitLibrary[2/29/2016 IT];
  879. /* 描述:Initialize Winsock library. This function calls WSAStartup;
  880. /* 参数:;
  881. /* [IN] wVersion:Winsock version use MAKEWORD macro if possible (e.g.: MAKEWORD(2,2));
  882. /* 返回:return true if successful;
  883. /* 注意:关联ReleaseLibrary;
  884. /* 示例:;
  885. /*
  886. /* 修改:;
  887. /* 日期:;
  888. /* 内容:;
  889. /************************************************************************/
  890. bool CSocketHandle::InitLibrary(IN WORD wVersion)
  891. {
  892. #ifdef WIN32
  893. WSADATA WSAData = { 0 };
  894. return ( 0 == WSAStartup( wVersion, &WSAData ) );
  895. #else
  896. return true;
  897. #endif
  898. }
  899. /************************************************************************/
  900. /* 函数:ReleaseLibrary[2/29/2016 IT];
  901. /* 描述:Release Winsock library;
  902. /* 参数:;
  903. /* 返回:return true if successful;
  904. /* 注意:关联InitLibrary;
  905. /* 示例:;
  906. /*
  907. /* 修改:;
  908. /* 日期:;
  909. /* 内容:;
  910. /************************************************************************/
  911. bool CSocketHandle::ReleaseLibrary()
  912. {
  913. #ifdef WIN32
  914. return ( 0 == WSACleanup() );
  915. #else
  916. return true;
  917. #endif
  918. }
  919. /************************************************************************/
  920. /* 函数:WaitForConnection[2/29/2016 IT];
  921. /* 描述:Wait for a new connection;
  922. /* 参数:;
  923. /* [IN] sock:A TCP socket handle. A new socket is return returned;
  924. /* 返回:return A new socket when a new client connects;
  925. /* 注意:关联GetSocket, CreateSocket;
  926. /* 示例:;
  927. /*
  928. /* 修改:;
  929. /* 日期:;
  930. /* 内容:;
  931. /************************************************************************/
  932. SOCKET CSocketHandle::WaitForConnection(IN SOCKET sock)
  933. {
  934. #if 0
  935. return accept(sock, 0, 0);
  936. #else
  937. SOCKET ncs = accept(sock, 0, 0);
  938. SetKeepLive(ncs);
  939. return ncs;
  940. #endif
  941. }
  942. /************************************************************************/
  943. /* 函数:ShutdownConnection[2/29/2016 IT];
  944. /* 描述:Shutdown a connection;
  945. /* 参数:;
  946. /* [IN] sock:Socket to shutdown communication;
  947. /* 返回:return true if successful;
  948. /* 注意:;
  949. /* 示例:;
  950. /*
  951. /* 修改:;
  952. /* 日期:;
  953. /* 内容:;
  954. /************************************************************************/
  955. bool CSocketHandle::ShutdownConnection(IN SOCKET sock)
  956. {
  957. shutdown(sock, SD_BOTH);
  958. return ( 0 == closesocket( sock ));
  959. }
  960. static unsigned char chMinClassA_IP [] = { 1, 0, 0, 0 } ;
  961. static unsigned char chMinClassD_IP [] = { 224, 0, 0, 0 } ;
  962. static unsigned char chMaxClassD_IP [] = { 239, 255, 255, 255 } ;
  963. /************************************************************************/
  964. /* 函数:IsUnicastIP[2/29/2016 IT];
  965. /* 描述:Check if IP address is unicast (network order);
  966. /* 参数:;
  967. /* [IN] ulAddr:IP address (expected valid unicast address);
  968. /* 返回:return true if successful;
  969. /* 注意:;
  970. /* 示例:;
  971. /*
  972. /* 修改:;
  973. /* 日期:;
  974. /* 内容:;
  975. /************************************************************************/
  976. bool CSocketHandle::IsUnicastIP( ULONG ulAddr )
  977. {
  978. return (((unsigned char *) & ulAddr) [0] >= chMinClassA_IP [0] &&
  979. ((unsigned char *) & ulAddr) [0] < chMinClassD_IP [0]) ;
  980. }
  981. /************************************************************************/
  982. /* 函数:IsMulticastIP[2/29/2016 IT];
  983. /* 描述:Check if IP address is multicast (network order);
  984. /* 参数:;
  985. /* [IN] ulAddr:IP address (expected valid multicast address);
  986. /* 返回:return true if successful;
  987. /* 注意:;
  988. /* 示例:;
  989. /*
  990. /* 修改:;
  991. /* 日期:;
  992. /* 内容:;
  993. /************************************************************************/
  994. bool CSocketHandle::IsMulticastIP( ULONG ulAddr )
  995. {
  996. return (((unsigned char *) & ulAddr) [0] >= chMinClassD_IP [0] &&
  997. ((unsigned char *) & ulAddr) [0] <= chMaxClassD_IP [0]) ;
  998. }
  999. /************************************************************************/
  1000. /* 函数:FormatIP[2/29/2016 IT];
  1001. /* 描述:Format IP address to string;
  1002. /* 参数:;
  1003. /* [IN] pszIPAddr:Buffer to hold string;
  1004. /* [IN] nSize:Size of buffer in characters;
  1005. /* [IN] ulAddr:IP Address to format;
  1006. /* [IN] bFmtHost:Specify if address (ulAddr) is in host (true) or network format (false);
  1007. /* 返回:return true if successful. Possible error could be INSUFFICIENT_BUFFER;
  1008. /* 注意:;
  1009. /* 示例:;
  1010. /*
  1011. /* 修改:;
  1012. /* 日期:;
  1013. /* 内容:;
  1014. /************************************************************************/
  1015. bool CSocketHandle::FormatIP(LPTSTR pszIPAddr, UINT nSize, ULONG ulAddr, bool bFmtHost)
  1016. {
  1017. if ( pszIPAddr && nSize > 8)
  1018. {
  1019. if ( bFmtHost )
  1020. ulAddr = htonl( ulAddr );
  1021. // Create Address string
  1022. return (SUCCEEDED(StringCchPrintf(pszIPAddr, nSize, TEXT("%u.%u.%u.%u"),
  1023. (UINT)(((PBYTE) &ulAddr)[0]),
  1024. (UINT)(((PBYTE) &ulAddr)[1]),
  1025. (UINT)(((PBYTE) &ulAddr)[2]),
  1026. (UINT)(((PBYTE) &ulAddr)[3]))));
  1027. }
  1028. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  1029. return false;
  1030. }
  1031. /************************************************************************/
  1032. /* 函数:FormatIP[2/29/2016 IT];
  1033. /* 描述:Format IP address to string;
  1034. /* 参数:;
  1035. /* [IN] pszIPAddr:Buffer to hold string;
  1036. /* [IN] nSize:Size of buffer in characters;
  1037. /* [IN] addrIn:IP Address to format;
  1038. /* 返回:return true if successful. Possible error could be INSUFFICIENT_BUFFER;
  1039. /* 注意:;
  1040. /* 示例:;
  1041. /*
  1042. /* 修改:;
  1043. /* 日期:;
  1044. /* 内容:;
  1045. /************************************************************************/
  1046. bool CSocketHandle::FormatIP(LPTSTR pszIPAddr, UINT nSize, const SockAddrIn& addrIn)
  1047. {
  1048. if ( pszIPAddr && nSize > 8)
  1049. {
  1050. const void* addr;
  1051. char szIPAddr[MAX_PATH] = { 0 };
  1052. if (addrIn.ss_family == AF_INET) {
  1053. addr = &((const sockaddr_in*)&addrIn)->sin_addr;
  1054. } else {
  1055. addr = &((const sockaddr_in6*)&addrIn)->sin6_addr;
  1056. }
  1057. if (inet_ntop(addrIn.ss_family, const_cast<void*>(addr), szIPAddr, MAX_PATH) != NULL)
  1058. {
  1059. #ifdef _UNICODE
  1060. return (0 != MultiByteToWideChar(CP_UTF8, 0, szIPAddr, -1, pszIPAddr, nSize ));
  1061. #else
  1062. ::StringCbCopyA(pszIPAddr, nSize, szIPAddr);
  1063. return true;
  1064. #endif
  1065. }
  1066. }
  1067. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  1068. return false;
  1069. }
  1070. /************************************************************************/
  1071. /* 函数:GetPortNumber[2/29/2016 IT];
  1072. /* 描述:Get service port number;
  1073. /* 参数:;
  1074. /* [IN] pszServiceName:Network service name (e.g.: "ftp", "telnet") or port number;
  1075. /* 返回:return port number;
  1076. /* 注意:;
  1077. /* 示例:;
  1078. /*
  1079. /* 修改:;
  1080. /* 日期:;
  1081. /* 内容:;
  1082. /************************************************************************/
  1083. USHORT CSocketHandle::GetPortNumber( LPCTSTR pszServiceName )
  1084. {
  1085. LPSERVENT lpservent;
  1086. USHORT nPort = 0;
  1087. if ( _istdigit( pszServiceName[0] ) ) {
  1088. nPort = (USHORT) _ttoi( pszServiceName );
  1089. }
  1090. else {
  1091. #ifdef _UNICODE
  1092. char pstrService[HOSTNAME_SIZE] = { 0 };
  1093. WideCharToMultiByte(CP_UTF8, 0, pszServiceName, -1, pstrService, sizeof(pstrService), NULL, NULL );
  1094. #else
  1095. LPCTSTR pstrService = pszServiceName;
  1096. #endif
  1097. // Convert network byte order to host byte order
  1098. if ( (lpservent = getservbyname( pstrService, NULL )) != NULL )
  1099. nPort = ntohs( lpservent->s_port );
  1100. }
  1101. return nPort;
  1102. }
  1103. /************************************************************************/
  1104. /* 函数:GetIPAddress[2/29/2016 IT];
  1105. /* 描述:Get IP address of a host;
  1106. /* 参数:;
  1107. /* [IN] pszHostName:host name or IP address;
  1108. /* 返回:return Host IP address in host format;
  1109. /* 注意:关联GetAddressInfo;
  1110. /* 示例:;
  1111. /*
  1112. /* 修改:;
  1113. /* 日期:;
  1114. /* 内容:;
  1115. /************************************************************************/
  1116. ULONG CSocketHandle::GetIPAddress( LPCTSTR pszHostName )
  1117. {
  1118. LPHOSTENT lphostent;
  1119. ULONG uAddr = INADDR_NONE;
  1120. TCHAR szLocal[HOSTNAME_SIZE] = { 0 };
  1121. // if no name specified, get local
  1122. if ( NULL == pszHostName || !pszHostName[0])
  1123. {
  1124. GetLocalName(szLocal, HOSTNAME_SIZE);
  1125. pszHostName = szLocal;
  1126. }
  1127. #ifdef _UNICODE
  1128. char pstrHost[HOSTNAME_SIZE] = { 0 };
  1129. WideCharToMultiByte(CP_UTF8, 0, pszHostName, -1, pstrHost, sizeof(pstrHost), NULL, NULL );
  1130. #else
  1131. LPCTSTR pstrHost = pszHostName;
  1132. #endif
  1133. // Check for an Internet Protocol dotted address string
  1134. uAddr = inet_addr( pstrHost );
  1135. if ( (INADDR_NONE == uAddr) && (strcmp( pstrHost, "255.255.255.255" )) )
  1136. {
  1137. // It's not an address, then try to resolve it as a hostname
  1138. if ( (lphostent = gethostbyname( pstrHost )) != NULL )
  1139. uAddr = *((ULONG *) lphostent->h_addr_list[0]);
  1140. }
  1141. return ntohl( uAddr );
  1142. }
  1143. /************************************************************************/
  1144. /* 函数:GetLocalName[2/29/2016 IT];
  1145. /* 描述:Get current localname for this machine;
  1146. /* 参数:;
  1147. /* [IN] pszName:Buffer to receive host name;
  1148. /* [IN] nSize:Size of this buffer in character;
  1149. /* 返回:return true if successful;
  1150. /* 注意:;
  1151. /* 示例:;
  1152. /*
  1153. /* 修改:;
  1154. /* 日期:;
  1155. /* 内容:;
  1156. /************************************************************************/
  1157. bool CSocketHandle::GetLocalName(LPTSTR pszName, UINT nSize)
  1158. {
  1159. if (pszName != NULL && nSize > 0)
  1160. {
  1161. char szHost[HOSTNAME_SIZE] = { 0 };
  1162. // get host name, if fail, SetLastError is set
  1163. if (SOCKET_ERROR != gethostname(szHost, sizeof(szHost)))
  1164. {
  1165. struct hostent* hp;
  1166. hp = gethostbyname(szHost);
  1167. if (hp != NULL) {
  1168. ::StringCbCopyA(szHost, HOSTNAME_SIZE, hp->h_name);
  1169. }
  1170. // check if user provide enough buffer
  1171. size_t cbLength = 0;
  1172. ::StringCbLengthA(szHost, HOSTNAME_SIZE, &cbLength);
  1173. if ( cbLength > nSize )
  1174. {
  1175. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  1176. return false;
  1177. }
  1178. // Unicode conversion
  1179. #ifdef _UNICODE
  1180. return (0 != MultiByteToWideChar(CP_UTF8, 0, szHost, -1, pszName, nSize ));
  1181. #else
  1182. ::StringCbCopyA(pszName, nSize, szHost);
  1183. return true;
  1184. #endif
  1185. }
  1186. else
  1187. SetLastError( WSAGetLastError() );
  1188. }
  1189. else
  1190. SetLastError(ERROR_INVALID_PARAMETER);
  1191. return false;
  1192. }
  1193. /************************************************************************/
  1194. /* 函数:GetLocalAddress[2/29/2016 IT];
  1195. /* 描述:Get current (default) IP address for this machine;
  1196. /* 参数:;
  1197. /* [IN] pszAddress:Buffer to receive IP address (IPv4, IPv6 format);
  1198. /* [IN] nSize:Size of this buffer in character;
  1199. /* [IN] nFamily:address family to use (AF_INET, AF_INET6);
  1200. /* 返回:return true if successful;
  1201. /* 注意:;
  1202. /* 示例:;
  1203. /*
  1204. /* 修改:;
  1205. /* 日期:;
  1206. /* 内容:;
  1207. /************************************************************************/
  1208. bool CSocketHandle::GetLocalAddress(LPTSTR pszAddress, UINT nSize, int nFamily /*= AF_INET*/)
  1209. {
  1210. if (pszAddress != NULL && nSize > 0)
  1211. {
  1212. TCHAR szHost[HOSTNAME_SIZE] = { 0 };
  1213. // Get computer local address
  1214. // get host name, if fail, SetLastError is set
  1215. if (GetLocalName(szHost, HOSTNAME_SIZE))
  1216. {
  1217. char szAddress[MAX_PATH] = { 0 };
  1218. #ifdef _UNICODE
  1219. char pstrHost[HOSTNAME_SIZE] = { 0 };
  1220. WideCharToMultiByte(CP_UTF8, 0, szHost, -1, pstrHost, sizeof(pstrHost), NULL, NULL );
  1221. #else
  1222. LPCTSTR pstrHost = szHost;
  1223. #endif
  1224. // get address info
  1225. sockaddr_storage addr_store = { 0 };
  1226. addr_store.ss_family = static_cast<short>(nFamily);
  1227. inet_pton(nFamily, pstrHost, &addr_store);
  1228. const void* addr;
  1229. if (addr_store.ss_family == AF_INET) {
  1230. addr = &((const sockaddr_in*)&addr_store)->sin_addr;
  1231. } else {
  1232. addr = &((const sockaddr_in6*)&addr_store)->sin6_addr;
  1233. }
  1234. if (inet_ntop(addr_store.ss_family, const_cast<void*>(addr), szAddress, MAX_PATH) != NULL)
  1235. {
  1236. // Unicode conversion
  1237. #ifdef _UNICODE
  1238. return (0 != MultiByteToWideChar(CP_UTF8, 0, szAddress, -1, pszAddress, nSize ));
  1239. #else
  1240. ::StringCbCopyA(pszAddress, nSize, szAddress);
  1241. return true;
  1242. #endif
  1243. }
  1244. else
  1245. SetLastError( WSAGetLastError() );
  1246. }
  1247. }
  1248. else
  1249. SetLastError(ERROR_INVALID_PARAMETER);
  1250. return false;
  1251. }
  1252. /************************************************************************/
  1253. /* 函数:GetAddressInfo[2/29/2016 IT];
  1254. /* 描述:Get IP address info of a host (Supports: IPv4 and IPv6);
  1255. /* 参数:;
  1256. /* [IN] pszHostName:host name or IP address;
  1257. /* [IN] pszServiceName:pszServiceName Network service name (e.g.: "ftp", "telnet") or port number;
  1258. /* [IN] nFamily:address family to use (AF_INET, AF_INET6);
  1259. /* [IN] sockAddr:Socket address to fill in;
  1260. /* 返回:return true if successful;
  1261. /* 注意:;
  1262. /* 示例:;
  1263. /*
  1264. /* 修改:;
  1265. /* 日期:;
  1266. /* 内容:;
  1267. /************************************************************************/
  1268. bool CSocketHandle::GetAddressInfo(LPCTSTR pszHostName, LPCTSTR pszServiceName,int nFamily, SockAddrIn& sockAddr)
  1269. {
  1270. const TCHAR szZERO[] = TEXT("0");
  1271. ADDRINFO aiHints;
  1272. ADDRINFO *aiList = NULL;
  1273. memset(&aiHints, 0, sizeof(aiHints));
  1274. aiHints.ai_flags = AI_ADDRCONFIG; // Jeff.暂时禁掉;
  1275. aiHints.ai_family = static_cast<short>(nFamily);
  1276. TCHAR szLocal[HOSTNAME_SIZE] = { 0 };
  1277. // if no name specified, get local
  1278. if ( NULL == pszHostName || !pszHostName[0])
  1279. {
  1280. GetLocalName(szLocal, HOSTNAME_SIZE);
  1281. pszHostName = szLocal;
  1282. }
  1283. if ( NULL == pszServiceName || !pszServiceName[0])
  1284. {
  1285. pszServiceName = szZERO;
  1286. }
  1287. #ifdef _UNICODE
  1288. char pstrHost[HOSTNAME_SIZE] = { 0 };
  1289. WideCharToMultiByte(CP_UTF8, 0, pszHostName, -1, pstrHost, sizeof(pstrHost), NULL, NULL );
  1290. char pstrService[HOSTNAME_SIZE] = { 0 };
  1291. WideCharToMultiByte(CP_UTF8, 0, pszServiceName, -1, pstrService, sizeof(pstrService), NULL, NULL );
  1292. #else
  1293. LPCTSTR pstrHost = pszHostName;
  1294. LPCTSTR pstrService = pszServiceName;
  1295. #endif
  1296. if ( SOCKET_ERROR != getaddrinfo(pstrHost, pstrService, &aiHints, &aiList) && ( aiList != 0 ))
  1297. {
  1298. ADDRINFO ai = { 0 };
  1299. ai.ai_addr = sockAddr;
  1300. memcpy(ai.ai_addr, aiList->ai_addr, aiList->ai_addrlen);
  1301. freeaddrinfo( aiList );
  1302. return true;
  1303. }
  1304. SetLastError( WSAGetLastError() );
  1305. return false;
  1306. }
  1307. ///////////////////////////////////////////////////////////////////////////////
  1308. // Globals
  1309. ///////////////////////////////////////////////////////////////////////////////
  1310. #if !defined(PLATFORM_HAS_INETFUNC)
  1311. #if 0
  1312. ///////////////////////////////////////////////////////////////////////////////
  1313. // inet_ntop
  1314. const char *inet_ntop(int af, const void *src, char *dst, size_t cnt)
  1315. {
  1316. if ( dst != NULL)
  1317. {
  1318. dst[0] = 0;
  1319. if (af == AF_INET)
  1320. {
  1321. sockaddr_in in;
  1322. memset(&in, 0, sizeof(in));
  1323. in.sin_family = AF_INET;
  1324. memcpy(&in.sin_addr, src, sizeof(in_addr));
  1325. getnameinfo((sockaddr *)&in, sizeof(sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
  1326. return dst;
  1327. }
  1328. else if (af == AF_INET6)
  1329. {
  1330. sockaddr_in6 in;
  1331. memset(&in, 0, sizeof(in));
  1332. in.sin6_family = AF_INET6;
  1333. memcpy(&in.sin6_addr, src, sizeof(in6_addr));
  1334. getnameinfo((sockaddr *)&in, sizeof(sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
  1335. return dst;
  1336. }
  1337. }
  1338. WSASetLastError(WSA_INVALID_PARAMETER);
  1339. return dst;
  1340. }
  1341. ///////////////////////////////////////////////////////////////////////////////
  1342. // inet_pton
  1343. int inet_pton(int af, const char *src, void *dst)
  1344. {
  1345. int result = SOCKET_ERROR;
  1346. addrinfo aiHints, *aiList = NULL;
  1347. memset(&aiHints, 0, sizeof(aiHints));
  1348. aiHints.ai_family = af;
  1349. if ( SOCKET_ERROR != getaddrinfo(src, NULL, &aiHints, &aiList) && (aiList != NULL))
  1350. {
  1351. memcpy(dst, aiList->ai_addr, aiList->ai_addrlen);
  1352. freeaddrinfo(aiList);
  1353. result = 0;
  1354. }
  1355. return result;
  1356. }
  1357. #else
  1358. //////////////////////////////////////////////////////////////////////////
  1359. static const char * inet_ntop_v4 (const void *src, char *dst, size_t size)
  1360. {
  1361. const char digits[] = "0123456789";
  1362. int i;
  1363. struct in_addr *addr = (struct in_addr *)src;
  1364. u_long a = ntohl(addr->s_addr);
  1365. const char *orig_dst = dst;
  1366. if (size < INET_ADDRSTRLEN) {
  1367. errno = ENOSPC;
  1368. return NULL;
  1369. }
  1370. for (i = 0; i < 4; ++i) {
  1371. int n = (a >> (24 - i * 8)) & 0xFF;
  1372. int non_zerop = 0;
  1373. if (non_zerop || n / 100 > 0) {
  1374. *dst++ = digits[n / 100];
  1375. n %= 100;
  1376. non_zerop = 1;
  1377. }
  1378. if (non_zerop || n / 10 > 0) {
  1379. *dst++ = digits[n / 10];
  1380. n %= 10;
  1381. non_zerop = 1;
  1382. }
  1383. *dst++ = digits[n];
  1384. if (i != 3)
  1385. *dst++ = '.';
  1386. }
  1387. *dst++ = '\0';
  1388. return orig_dst;
  1389. }
  1390. #ifdef HAVE_IPV6
  1391. static const char * inet_ntop_v6 (const void *src, char *dst, size_t size)
  1392. {
  1393. const char xdigits[] = "0123456789abcdef";
  1394. int i;
  1395. const struct in6_addr *addr = (struct in6_addr *)src;
  1396. const u_char *ptr = addr->s6_addr;
  1397. const char *orig_dst = dst;
  1398. int compressed = 0;
  1399. if (size < INET6_ADDRSTRLEN) {
  1400. errno = ENOSPC;
  1401. return NULL;
  1402. }
  1403. for (i = 0; i < 8; ++i) {
  1404. int non_zerop = 0;
  1405. if (compressed == 0 &&
  1406. ptr[0] == 0 && ptr[1] == 0 &&
  1407. i <= 5 &&
  1408. ptr[2] == 0 && ptr[3] == 0 &&
  1409. ptr[4] == 0 && ptr[5] == 0) {
  1410. compressed = 1;
  1411. if (i == 0)
  1412. *dst++ = ':';
  1413. *dst++ = ':';
  1414. for (ptr += 6, i += 3;
  1415. i < 8 && ptr[0] == 0 && ptr[1] == 0;
  1416. ++i, ptr += 2);
  1417. if (i >= 8)
  1418. break;
  1419. }
  1420. if (non_zerop || (ptr[0] >> 4)) {
  1421. *dst++ = xdigits[ptr[0] >> 4];
  1422. non_zerop = 1;
  1423. }
  1424. if (non_zerop || (ptr[0] & 0x0F)) {
  1425. *dst++ = xdigits[ptr[0] & 0x0F];
  1426. non_zerop = 1;
  1427. }
  1428. if (non_zerop || (ptr[1] >> 4)) {
  1429. *dst++ = xdigits[ptr[1] >> 4];
  1430. non_zerop = 1;
  1431. }
  1432. *dst++ = xdigits[ptr[1] & 0x0F];
  1433. if (i != 7)
  1434. *dst++ = ':';
  1435. ptr += 2;
  1436. }
  1437. *dst++ = '\0';
  1438. return orig_dst;
  1439. }
  1440. #endif /* HAVE_IPV6 */
  1441. const char * inet_ntop(int af, const void *src, char *dst, size_t size)
  1442. {
  1443. switch (af) {
  1444. case AF_INET :
  1445. return inet_ntop_v4 (src, dst, size);
  1446. #ifdef HAVE_IPV6
  1447. case AF_INET6 :
  1448. return inet_ntop_v6 (src, dst, size);
  1449. #endif
  1450. default :
  1451. //errno = EAFNOSUPPORT;
  1452. return NULL;
  1453. }
  1454. }
  1455. int inet_pton(int af, const char *csrc, void *dst)
  1456. {
  1457. char * src;
  1458. if (csrc == NULL || (src = strdup(csrc)) == NULL) {
  1459. _set_errno( ENOMEM );
  1460. return 0;
  1461. }
  1462. switch (af) {
  1463. case AF_INET:
  1464. {
  1465. struct sockaddr_in si4;
  1466. INT r;
  1467. INT s = sizeof(si4);
  1468. si4.sin_family = AF_INET;
  1469. r = WSAStringToAddress(src, AF_INET, NULL, (LPSOCKADDR) &si4, &s);
  1470. free(src);
  1471. src = NULL;
  1472. if (r == 0) {
  1473. memcpy(dst, &si4.sin_addr, sizeof(si4.sin_addr));
  1474. return 1;
  1475. }
  1476. }
  1477. break;
  1478. case AF_INET6:
  1479. {
  1480. struct sockaddr_in6 si6;
  1481. INT r;
  1482. INT s = sizeof(si6);
  1483. si6.sin6_family = AF_INET6;
  1484. r = WSAStringToAddress(src, AF_INET6, NULL, (LPSOCKADDR) &si6, &s);
  1485. free(src);
  1486. src = NULL;
  1487. if (r == 0) {
  1488. memcpy(dst, &si6.sin6_addr, sizeof(si6.sin6_addr));
  1489. return 1;
  1490. }
  1491. }
  1492. break;
  1493. default:
  1494. _set_errno( ENOSYS/*EAFNOSUPPORT*/ );
  1495. return -1;
  1496. }
  1497. /* the call failed */
  1498. {
  1499. int le = WSAGetLastError();
  1500. if (le == WSAEINVAL)
  1501. return 0;
  1502. _set_errno(le);
  1503. return -1;
  1504. }
  1505. }
  1506. #endif
  1507. #endif