SocketHandle.cpp 43 KB

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