SocketHandle.cpp 43 KB

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