SocketHandle.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635
  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. closesocket( sock );
  550. return false;
  551. }
  552. // Success, now we may save this socket
  553. m_hSocket = sock;
  554. }
  555. return (INVALID_SOCKET != sock);
  556. }
  557. /************************************************************************/
  558. /* 函数:Read[2/29/2016 IT];
  559. /* 描述:从套接字中读取内容;
  560. /* 参数:;
  561. /* [OUT] lpBuffer:Buffer to receive data;
  562. /* [IN] dwSize:Size of buffer in bytes;
  563. /* [IN] lpAddrIn:Peer address for UDP - this must be NULL for TCP;
  564. /* [IN] dwTimeout:Read timeout in milliseconds;
  565. /* 返回:return number of bytes read or (-1L) if fail;
  566. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, Write, WriteEx;
  567. /* 示例:;
  568. /*
  569. /* 修改:;
  570. /* 日期:;
  571. /* 内容:;
  572. /************************************************************************/
  573. DWORD CSocketHandle::Read(OUT LPBYTE lpBuffer, IN DWORD dwSize, IN LPSOCKADDR lpAddrIn /* = NULL */, IN DWORD dwTimeout /* = INFINITE */)
  574. {
  575. _ASSERTE( IsOpen() );
  576. _ASSERTE( lpBuffer != NULL );
  577. if (!IsOpen() || lpBuffer == NULL || dwSize < 1L)
  578. return (DWORD)-1L;
  579. fd_set fdRead = { 0 };
  580. TIMEVAL stTime;
  581. TIMEVAL *pstTime = NULL;
  582. if ( INFINITE != dwTimeout ) {
  583. stTime.tv_sec = dwTimeout/1000;
  584. stTime.tv_usec = (dwTimeout%1000)*1000;
  585. pstTime = &stTime;
  586. }
  587. SOCKET s = GetSocket();
  588. // Set Descriptor
  589. FD_SET( s, &fdRead );
  590. // Select function set read timeout
  591. DWORD dwBytesRead = 0L;
  592. int res = 1;
  593. if ( pstTime != NULL )
  594. res = select((int)s, &fdRead, NULL, NULL, pstTime );
  595. if ( res > 0)
  596. {
  597. if (lpAddrIn)
  598. {
  599. // UDP
  600. socklen_t fromlen = sizeof(SOCKADDR_STORAGE);
  601. res = recvfrom(s, reinterpret_cast<LPSTR>(lpBuffer), dwSize, 0, lpAddrIn, &fromlen);
  602. }
  603. else
  604. {
  605. // TCP
  606. res = recv(s, reinterpret_cast<LPSTR>(lpBuffer), dwSize, 0);
  607. }
  608. if ( res == 0 ) {
  609. WSASetLastError(WSAECONNRESET);
  610. res = SOCKET_ERROR;
  611. }
  612. }
  613. if ( res == SOCKET_ERROR )
  614. {
  615. SetLastError( WSAGetLastError() );
  616. }
  617. dwBytesRead = (DWORD)((res >= 0)?(res) : (-1));
  618. return dwBytesRead;
  619. }
  620. #ifdef WIN32
  621. /************************************************************************/
  622. /* 函数:ReadEx[2/29/2016 IT];
  623. /* 描述:从套接字读取内容,异步模式(asynchronous mode);
  624. /* 参数:;
  625. /* [OUT] lpBuffer:Buffer to receive data;
  626. /* [IN] dwSize:Size of buffer in bytes;
  627. /* [IN] lpAddrIn:SockAddrIn for UDP - this must be NULL for TCP;
  628. /* [IN] lpOverlapped:Windows Overlapped structure (required);
  629. /* [IN] lpCompletionRoutine:Winsock Completion routine (required);
  630. /* 返回:return number of bytes read, overlapped operation is pending or (-1L) if fail;
  631. /* 注意:关联函数 InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, Write, WriteEx, IOControl, GetTransferOverlappedResult;
  632. /* 示例:;
  633. /*
  634. /* 修改:;
  635. /* 日期:;
  636. /* 内容:;
  637. /************************************************************************/
  638. DWORD CSocketHandle::ReadEx(OUT LPBYTE lpBuffer, IN DWORD dwSize, IN LPSOCKADDR lpAddrIn, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSACOMPLETIONROUTINE lpCompletionRoutine)
  639. {
  640. _ASSERTE( IsOpen() );
  641. _ASSERTE( lpBuffer != NULL );
  642. if (!IsOpen() || lpBuffer == NULL || dwSize < 1L)
  643. return (DWORD)-1L;
  644. SOCKET s = GetSocket();
  645. // Send message to peer
  646. WSABUF wsabuf;
  647. wsabuf.buf = (char FAR*)lpBuffer;
  648. wsabuf.len = dwSize;
  649. // Select function set read timeout
  650. DWORD dwBytesRead = 0L;
  651. DWORD dwFlags = 0L;
  652. int res = 0;
  653. if (lpAddrIn)
  654. {
  655. // UDP
  656. socklen_t fromlen = sizeof(SOCKADDR_STORAGE);
  657. res = WSARecvFrom( s, &wsabuf, 1, &dwBytesRead, &dwFlags, lpAddrIn, &fromlen, lpOverlapped, lpCompletionRoutine);
  658. }
  659. else
  660. {
  661. // TCP
  662. res = WSARecv( s, &wsabuf, 1, &dwBytesRead, &dwFlags, lpOverlapped, lpCompletionRoutine);
  663. }
  664. if ( res == SOCKET_ERROR )
  665. {
  666. res = WSAGetLastError();
  667. if ( res != WSA_IO_PENDING )
  668. {
  669. dwBytesRead = (DWORD)-1L;
  670. SetLastError( res );
  671. }
  672. }
  673. return dwBytesRead;
  674. }
  675. #endif
  676. /************************************************************************/
  677. /* 函数:Write[2/29/2016 IT];
  678. /* 描述:向目标套接字发送内容;
  679. /* 参数:;
  680. /* [IN] lpBuffer:Buffer to send;
  681. /* [IN] dwCount:Number of bytes to send;
  682. /* [IN] lpAddrIn:Peer address for UDP - this must be NULL for TCP;
  683. /* [IN] dwTimeout:Write timeout in milliseconds;
  684. /* 返回:return number of bytes sent or (-1L) if fail;
  685. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, ReadEx, WriteEx;
  686. /* 示例:;
  687. /*
  688. /* 修改:;
  689. /* 日期:;
  690. /* 内容:;
  691. /************************************************************************/
  692. DWORD CSocketHandle::Write(IN const LPBYTE lpBuffer, IN DWORD dwCount, IN const LPSOCKADDR lpAddrIn /* = NULL */, IN DWORD dwTimeout /* = INFINITE */)
  693. {
  694. _ASSERTE( IsOpen() );
  695. _ASSERTE( NULL != lpBuffer );
  696. // validate params
  697. if (!IsOpen() || NULL == lpBuffer)
  698. return (DWORD)-1L;
  699. fd_set fdWrite = { 0 };
  700. TIMEVAL stTime;
  701. TIMEVAL *pstTime = NULL;
  702. if ( INFINITE != dwTimeout ) {
  703. stTime.tv_sec = dwTimeout/1000;
  704. stTime.tv_usec = (dwTimeout%1000)*1000;
  705. pstTime = &stTime;
  706. }
  707. SOCKET s = GetSocket();
  708. // Set Descriptor
  709. FD_SET( s, &fdWrite );
  710. // Select function set write timeout
  711. DWORD dwBytesWritten = 0L;
  712. int res = 1;
  713. if ( pstTime != NULL )
  714. {
  715. res = select((int)s, NULL, &fdWrite, NULL, pstTime );
  716. }
  717. if ( res > 0)
  718. {
  719. // Send message to peer
  720. if (lpAddrIn)
  721. {
  722. // UDP
  723. res = sendto( s, reinterpret_cast<LPCSTR>(lpBuffer), dwCount, 0, lpAddrIn, sizeof(SOCKADDR_STORAGE));
  724. }
  725. else
  726. {
  727. // TCP
  728. res = send( s, reinterpret_cast<LPCSTR>(lpBuffer), dwCount, 0);
  729. }
  730. }
  731. if ( res == SOCKET_ERROR )
  732. {
  733. SetLastError( WSAGetLastError() );
  734. }
  735. dwBytesWritten = (DWORD)((res >= 0)?(res) : (-1));
  736. return dwBytesWritten;
  737. }
  738. #ifdef WIN32
  739. /************************************************************************/
  740. /* 函数:WriteEx[2/29/2016 IT];
  741. /* 描述:向目标套接字发送内容,异步模式(asynchronous mode);
  742. /* 参数:;
  743. /* [IN] lpBuffer:Buffer to send;
  744. /* [IN] dwCount:Number of bytes to send;
  745. /* [IN] lpAddrIn:SockAddrIn for UDP - this must be NULL for TCP;
  746. /* [IN] lpOverlapped:Windows Overlapped structure (required);
  747. /* [IN] lpCompletionRoutine:Winsock Completion routine (required);
  748. /* 返回:return number of bytes read, overlapped operation is pending or (-1L) if fail;
  749. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, ReadEx, Write, IOControl, GetTransferOverlappedResult;
  750. /* 示例:;
  751. /*
  752. /* 修改:;
  753. /* 日期:;
  754. /* 内容:;
  755. /************************************************************************/
  756. DWORD CSocketHandle::WriteEx(IN const LPBYTE lpBuffer, IN DWORD dwCount, IN const LPSOCKADDR lpAddrIn, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSACOMPLETIONROUTINE lpCompletionRoutine)
  757. {
  758. _ASSERTE( IsOpen() );
  759. _ASSERTE( NULL != lpBuffer );
  760. // validate params
  761. if (!IsOpen() || NULL == lpBuffer)
  762. return (DWORD)-1L;
  763. SOCKET s = GetSocket();
  764. // Select function set write timeout
  765. DWORD dwBytesWritten = 0L;
  766. int res = 0;
  767. // Send message to peer
  768. WSABUF wsabuf;
  769. wsabuf.buf = (char FAR*) lpBuffer;
  770. wsabuf.len = dwCount;
  771. if (lpAddrIn)
  772. {
  773. // UDP
  774. res = WSASendTo( s, &wsabuf, 1, &dwBytesWritten, 0, lpAddrIn, sizeof(SOCKADDR_STORAGE),
  775. lpOverlapped, lpCompletionRoutine);
  776. }
  777. else // TCP
  778. res = WSASend( s, &wsabuf, 1, &dwBytesWritten, 0, lpOverlapped, lpCompletionRoutine);
  779. if ( res == SOCKET_ERROR )
  780. {
  781. res = WSAGetLastError();
  782. if ( res != WSA_IO_PENDING )
  783. {
  784. dwBytesWritten = (DWORD)-1L;
  785. SetLastError( res );
  786. }
  787. }
  788. return dwBytesWritten;
  789. }
  790. #endif
  791. #ifdef WIN32
  792. /************************************************************************/
  793. /* 函数:IOControl[2/29/2016 IT];
  794. /* 描述:Control the mode of a socket (asynchronous mode);
  795. /* 参数:;
  796. /* [IN] dwIoCode:Control code of operation to perform;
  797. /* [IN] lpInBuffer:Pointer to the input buffer;
  798. /* [IN] cbInBuffer:Size of the input buffer, in bytes;
  799. /* [IN] lpOutBuffer:Pointer to the output buffer;
  800. /* [IN] cbOutBuffer:Size of the output buffer, in bytes;
  801. /* [IN] lpcbBytesReturned:Pointer to actual number of bytes of output;
  802. /* [IN] lpOverlapped:Winsock Overlapped structure;
  803. /* [IN] lpCompletionRoutine:Winsock Completion routine;
  804. /* 返回:return true if successful, otherwise false (call WSAGetLastError() to retrieve latest error);
  805. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, WriteEx, GetTransferOverlappedResult;
  806. /* 示例:;
  807. /*
  808. /* 修改:;
  809. /* 日期:;
  810. /* 内容:;
  811. /************************************************************************/
  812. bool CSocketHandle::IOControl(
  813. IN DWORD dwIoCode,
  814. IN LPBYTE lpInBuffer,
  815. IN DWORD cbInBuffer,
  816. IN LPBYTE lpOutBuffer,
  817. IN DWORD cbOutBuffer,
  818. IN LPDWORD lpcbBytesReturned,
  819. IN LPWSAOVERLAPPED lpOverlapped,
  820. IN LPWSACOMPLETIONROUTINE lpCompletionRoutine )
  821. {
  822. _ASSERTE( IsOpen() );
  823. // validate params
  824. if ( !IsOpen() ) {
  825. SetLastError(ERROR_INVALID_HANDLE);
  826. return false;
  827. }
  828. int res;
  829. SOCKET s = GetSocket();
  830. res = WSAIoctl(s, dwIoCode, lpInBuffer, cbInBuffer, lpOutBuffer, cbOutBuffer,
  831. lpcbBytesReturned, lpOverlapped, lpCompletionRoutine);
  832. if ( res == SOCKET_ERROR )
  833. {
  834. SetLastError( WSAGetLastError() );
  835. }
  836. return ( res != SOCKET_ERROR );
  837. }
  838. /************************************************************************/
  839. /* 函数:GetTransferOverlappedResult[2/29/2016 IT];
  840. /* 描述:Get Overlapped result (asynchronous mode);
  841. /* 参数:;
  842. /* [IN] lpOverlapped:Windows Overlapped structure (required);
  843. /* [IN] lpcbTransfer:Pointer to get number of bytes transferred;
  844. /* [IN] bWait:Force wait for overlapped operation to complete;
  845. /* [IN] lpdwFlags:Optional flags (see MSDN on WSARecv API);
  846. /* [OUT] :;
  847. /* [IN/OUT] :;
  848. /* 返回:成功返回TRUE;
  849. /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, WriteEx, IOControl;
  850. /* 示例:;
  851. /*
  852. /* 修改:;
  853. /* 日期:;
  854. /* 内容:;
  855. /************************************************************************/
  856. bool CSocketHandle::GetTransferOverlappedResult(IN LPWSAOVERLAPPED lpOverlapped, IN LPDWORD lpcbTransfer, IN bool bWait /* = true */, IN LPDWORD lpdwFlags /* = 0 */)
  857. {
  858. _ASSERTE( IsOpen() );
  859. _ASSERTE( NULL != lpOverlapped );
  860. // validate params
  861. if (!IsOpen() || NULL == lpOverlapped) {
  862. SetLastError(ERROR_INVALID_HANDLE);
  863. return false;
  864. }
  865. SOCKET s = GetSocket();
  866. DWORD dwFlags = 0;
  867. if ( lpdwFlags == NULL )
  868. lpdwFlags = &dwFlags;
  869. BOOL bRet = WSAGetOverlappedResult( s, lpOverlapped, lpcbTransfer, bWait, lpdwFlags );
  870. if ( !bRet )
  871. {
  872. SetLastError( WSAGetLastError() );
  873. }
  874. return (bRet != FALSE);
  875. }
  876. #endif
  877. ///////////////////////////////////////////////////////////////////////////////
  878. // Utility functions
  879. /************************************************************************/
  880. /* 函数:InitLibrary[2/29/2016 IT];
  881. /* 描述:Initialize Winsock library. This function calls WSAStartup;
  882. /* 参数:;
  883. /* [IN] wVersion:Winsock version use MAKEWORD macro if possible (e.g.: MAKEWORD(2,2));
  884. /* 返回:return true if successful;
  885. /* 注意:关联ReleaseLibrary;
  886. /* 示例:;
  887. /*
  888. /* 修改:;
  889. /* 日期:;
  890. /* 内容:;
  891. /************************************************************************/
  892. bool CSocketHandle::InitLibrary(IN WORD wVersion)
  893. {
  894. #ifdef WIN32
  895. WSADATA WSAData = { 0 };
  896. return ( 0 == WSAStartup( wVersion, &WSAData ) );
  897. #else
  898. return true;
  899. #endif
  900. }
  901. /************************************************************************/
  902. /* 函数:ReleaseLibrary[2/29/2016 IT];
  903. /* 描述:Release Winsock library;
  904. /* 参数:;
  905. /* 返回:return true if successful;
  906. /* 注意:关联InitLibrary;
  907. /* 示例:;
  908. /*
  909. /* 修改:;
  910. /* 日期:;
  911. /* 内容:;
  912. /************************************************************************/
  913. bool CSocketHandle::ReleaseLibrary()
  914. {
  915. #ifdef WIN32
  916. return ( 0 == WSACleanup() );
  917. #else
  918. return true;
  919. #endif
  920. }
  921. /************************************************************************/
  922. /* 函数:WaitForConnection[2/29/2016 IT];
  923. /* 描述:Wait for a new connection;
  924. /* 参数:;
  925. /* [IN] sock:A TCP socket handle. A new socket is return returned;
  926. /* 返回:return A new socket when a new client connects;
  927. /* 注意:关联GetSocket, CreateSocket;
  928. /* 示例:;
  929. /*
  930. /* 修改:;
  931. /* 日期:;
  932. /* 内容:;
  933. /************************************************************************/
  934. SOCKET CSocketHandle::WaitForConnection(IN SOCKET sock)
  935. {
  936. #if 0
  937. return accept(sock, 0, 0);
  938. #else
  939. SOCKET ncs = accept(sock, 0, 0);
  940. SetKeepLive(ncs);
  941. return ncs;
  942. #endif
  943. }
  944. /************************************************************************/
  945. /* 函数:ShutdownConnection[2/29/2016 IT];
  946. /* 描述:Shutdown a connection;
  947. /* 参数:;
  948. /* [IN] sock:Socket to shutdown communication;
  949. /* 返回:return true if successful;
  950. /* 注意:;
  951. /* 示例:;
  952. /*
  953. /* 修改:;
  954. /* 日期:;
  955. /* 内容:;
  956. /************************************************************************/
  957. bool CSocketHandle::ShutdownConnection(IN SOCKET sock)
  958. {
  959. shutdown(sock, SD_BOTH);
  960. return ( 0 == closesocket( sock ));
  961. }
  962. static unsigned char chMinClassA_IP [] = { 1, 0, 0, 0 } ;
  963. static unsigned char chMinClassD_IP [] = { 224, 0, 0, 0 } ;
  964. static unsigned char chMaxClassD_IP [] = { 239, 255, 255, 255 } ;
  965. /************************************************************************/
  966. /* 函数:IsUnicastIP[2/29/2016 IT];
  967. /* 描述:Check if IP address is unicast (network order);
  968. /* 参数:;
  969. /* [IN] ulAddr:IP address (expected valid unicast address);
  970. /* 返回:return true if successful;
  971. /* 注意:;
  972. /* 示例:;
  973. /*
  974. /* 修改:;
  975. /* 日期:;
  976. /* 内容:;
  977. /************************************************************************/
  978. bool CSocketHandle::IsUnicastIP( ULONG ulAddr )
  979. {
  980. return (((unsigned char *) & ulAddr) [0] >= chMinClassA_IP [0] &&
  981. ((unsigned char *) & ulAddr) [0] < chMinClassD_IP [0]) ;
  982. }
  983. /************************************************************************/
  984. /* 函数:IsMulticastIP[2/29/2016 IT];
  985. /* 描述:Check if IP address is multicast (network order);
  986. /* 参数:;
  987. /* [IN] ulAddr:IP address (expected valid multicast address);
  988. /* 返回:return true if successful;
  989. /* 注意:;
  990. /* 示例:;
  991. /*
  992. /* 修改:;
  993. /* 日期:;
  994. /* 内容:;
  995. /************************************************************************/
  996. bool CSocketHandle::IsMulticastIP( ULONG ulAddr )
  997. {
  998. return (((unsigned char *) & ulAddr) [0] >= chMinClassD_IP [0] &&
  999. ((unsigned char *) & ulAddr) [0] <= chMaxClassD_IP [0]) ;
  1000. }
  1001. /************************************************************************/
  1002. /* 函数:FormatIP[2/29/2016 IT];
  1003. /* 描述:Format IP address to string;
  1004. /* 参数:;
  1005. /* [IN] pszIPAddr:Buffer to hold string;
  1006. /* [IN] nSize:Size of buffer in characters;
  1007. /* [IN] ulAddr:IP Address to format;
  1008. /* [IN] bFmtHost:Specify if address (ulAddr) is in host (true) or network format (false);
  1009. /* 返回:return true if successful. Possible error could be INSUFFICIENT_BUFFER;
  1010. /* 注意:;
  1011. /* 示例:;
  1012. /*
  1013. /* 修改:;
  1014. /* 日期:;
  1015. /* 内容:;
  1016. /************************************************************************/
  1017. bool CSocketHandle::FormatIP(LPTSTR pszIPAddr, UINT nSize, ULONG ulAddr, bool bFmtHost)
  1018. {
  1019. if ( pszIPAddr && nSize > 8)
  1020. {
  1021. if ( bFmtHost )
  1022. ulAddr = htonl( ulAddr );
  1023. // Create Address string
  1024. return (SUCCEEDED(StringCchPrintf(pszIPAddr, nSize, TEXT("%u.%u.%u.%u"),
  1025. (UINT)(((PBYTE) &ulAddr)[0]),
  1026. (UINT)(((PBYTE) &ulAddr)[1]),
  1027. (UINT)(((PBYTE) &ulAddr)[2]),
  1028. (UINT)(((PBYTE) &ulAddr)[3]))));
  1029. }
  1030. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  1031. return false;
  1032. }
  1033. /************************************************************************/
  1034. /* 函数:FormatIP[2/29/2016 IT];
  1035. /* 描述:Format IP address to string;
  1036. /* 参数:;
  1037. /* [IN] pszIPAddr:Buffer to hold string;
  1038. /* [IN] nSize:Size of buffer in characters;
  1039. /* [IN] addrIn:IP Address to format;
  1040. /* 返回:return true if successful. Possible error could be INSUFFICIENT_BUFFER;
  1041. /* 注意:;
  1042. /* 示例:;
  1043. /*
  1044. /* 修改:;
  1045. /* 日期:;
  1046. /* 内容:;
  1047. /************************************************************************/
  1048. bool CSocketHandle::FormatIP(LPTSTR pszIPAddr, UINT nSize, const SockAddrIn& addrIn)
  1049. {
  1050. if ( pszIPAddr && nSize > 8)
  1051. {
  1052. const void* addr;
  1053. char szIPAddr[MAX_PATH] = { 0 };
  1054. if (addrIn.ss_family == AF_INET) {
  1055. addr = &((const sockaddr_in*)&addrIn)->sin_addr;
  1056. } else {
  1057. addr = &((const sockaddr_in6*)&addrIn)->sin6_addr;
  1058. }
  1059. if (_inet_ntop(addrIn.ss_family, const_cast<void*>(addr), szIPAddr, MAX_PATH) != NULL)
  1060. {
  1061. #ifdef _UNICODE
  1062. return (0 != MultiByteToWideChar(CP_UTF8, 0, szIPAddr, -1, pszIPAddr, nSize ));
  1063. #else
  1064. ::StringCbCopyA(pszIPAddr, nSize, szIPAddr);
  1065. return true;
  1066. #endif
  1067. }
  1068. }
  1069. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  1070. return false;
  1071. }
  1072. /************************************************************************/
  1073. /* 函数:GetPortNumber[2/29/2016 IT];
  1074. /* 描述:Get service port number;
  1075. /* 参数:;
  1076. /* [IN] pszServiceName:Network service name (e.g.: "ftp", "telnet") or port number;
  1077. /* 返回:return port number;
  1078. /* 注意:;
  1079. /* 示例:;
  1080. /*
  1081. /* 修改:;
  1082. /* 日期:;
  1083. /* 内容:;
  1084. /************************************************************************/
  1085. USHORT CSocketHandle::GetPortNumber( LPCTSTR pszServiceName )
  1086. {
  1087. LPSERVENT lpservent;
  1088. USHORT nPort = 0;
  1089. if ( _istdigit( pszServiceName[0] ) ) {
  1090. nPort = (USHORT) _ttoi( pszServiceName );
  1091. }
  1092. else {
  1093. #ifdef _UNICODE
  1094. char pstrService[HOSTNAME_SIZE] = { 0 };
  1095. WideCharToMultiByte(CP_UTF8, 0, pszServiceName, -1, pstrService, sizeof(pstrService), NULL, NULL );
  1096. #else
  1097. LPCTSTR pstrService = pszServiceName;
  1098. #endif
  1099. // Convert network byte order to host byte order
  1100. if ( (lpservent = getservbyname( pstrService, NULL )) != NULL )
  1101. nPort = ntohs( lpservent->s_port );
  1102. }
  1103. return nPort;
  1104. }
  1105. /************************************************************************/
  1106. /* 函数:GetIPAddress[2/29/2016 IT];
  1107. /* 描述:Get IP address of a host;
  1108. /* 参数:;
  1109. /* [IN] pszHostName:host name or IP address;
  1110. /* 返回:return Host IP address in host format;
  1111. /* 注意:关联GetAddressInfo;
  1112. /* 示例:;
  1113. /*
  1114. /* 修改:;
  1115. /* 日期:;
  1116. /* 内容:;
  1117. /************************************************************************/
  1118. ULONG CSocketHandle::GetIPAddress( LPCTSTR pszHostName )
  1119. {
  1120. LPHOSTENT lphostent;
  1121. ULONG uAddr = INADDR_NONE;
  1122. TCHAR szLocal[HOSTNAME_SIZE] = { 0 };
  1123. // if no name specified, get local
  1124. if ( NULL == pszHostName || !pszHostName[0])
  1125. {
  1126. GetLocalName(szLocal, HOSTNAME_SIZE);
  1127. pszHostName = szLocal;
  1128. }
  1129. #ifdef _UNICODE
  1130. char pstrHost[HOSTNAME_SIZE] = { 0 };
  1131. WideCharToMultiByte(CP_UTF8, 0, pszHostName, -1, pstrHost, sizeof(pstrHost), NULL, NULL );
  1132. #else
  1133. LPCTSTR pstrHost = pszHostName;
  1134. #endif
  1135. // Check for an Internet Protocol dotted address string
  1136. uAddr = inet_addr( pstrHost );
  1137. if ( (INADDR_NONE == uAddr) && (strcmp( pstrHost, "255.255.255.255" )) )
  1138. {
  1139. // It's not an address, then try to resolve it as a hostname
  1140. if ( (lphostent = gethostbyname( pstrHost )) != NULL )
  1141. uAddr = *((ULONG *) lphostent->h_addr_list[0]);
  1142. }
  1143. return ntohl( uAddr );
  1144. }
  1145. /************************************************************************/
  1146. /* 函数:GetLocalName[2/29/2016 IT];
  1147. /* 描述:Get current localname for this machine;
  1148. /* 参数:;
  1149. /* [IN] pszName:Buffer to receive host name;
  1150. /* [IN] nSize:Size of this buffer in character;
  1151. /* 返回:return true if successful;
  1152. /* 注意:;
  1153. /* 示例:;
  1154. /*
  1155. /* 修改:;
  1156. /* 日期:;
  1157. /* 内容:;
  1158. /************************************************************************/
  1159. bool CSocketHandle::GetLocalName(LPTSTR pszName, UINT nSize)
  1160. {
  1161. if (pszName != NULL && nSize > 0)
  1162. {
  1163. char szHost[HOSTNAME_SIZE] = { 0 };
  1164. // get host name, if fail, SetLastError is set
  1165. if (SOCKET_ERROR != gethostname(szHost, sizeof(szHost)))
  1166. {
  1167. struct hostent* hp;
  1168. hp = gethostbyname(szHost);
  1169. if (hp != NULL) {
  1170. ::StringCbCopyA(szHost, HOSTNAME_SIZE, hp->h_name);
  1171. }
  1172. // check if user provide enough buffer
  1173. size_t cbLength = 0;
  1174. ::StringCbLengthA(szHost, HOSTNAME_SIZE, &cbLength);
  1175. if ( cbLength > nSize )
  1176. {
  1177. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  1178. return false;
  1179. }
  1180. // Unicode conversion
  1181. #ifdef _UNICODE
  1182. return (0 != MultiByteToWideChar(CP_UTF8, 0, szHost, -1, pszName, nSize ));
  1183. #else
  1184. ::StringCbCopyA(pszName, nSize, szHost);
  1185. return true;
  1186. #endif
  1187. }
  1188. else
  1189. SetLastError( WSAGetLastError() );
  1190. }
  1191. else
  1192. SetLastError(ERROR_INVALID_PARAMETER);
  1193. return false;
  1194. }
  1195. /************************************************************************/
  1196. /* 函数:GetLocalAddress[2/29/2016 IT];
  1197. /* 描述:Get current (default) IP address for this machine;
  1198. /* 参数:;
  1199. /* [IN] pszAddress:Buffer to receive IP address (IPv4, IPv6 format);
  1200. /* [IN] nSize:Size of this buffer in character;
  1201. /* [IN] nFamily:address family to use (AF_INET, AF_INET6);
  1202. /* 返回:return true if successful;
  1203. /* 注意:;
  1204. /* 示例:;
  1205. /*
  1206. /* 修改:;
  1207. /* 日期:;
  1208. /* 内容:;
  1209. /************************************************************************/
  1210. bool CSocketHandle::GetLocalAddress(LPTSTR pszAddress, UINT nSize, int nFamily /*= AF_INET*/)
  1211. {
  1212. if (pszAddress != NULL && nSize > 0)
  1213. {
  1214. TCHAR szHost[HOSTNAME_SIZE] = { 0 };
  1215. // Get computer local address
  1216. // get host name, if fail, SetLastError is set
  1217. if (GetLocalName(szHost, HOSTNAME_SIZE))
  1218. {
  1219. char szAddress[MAX_PATH] = { 0 };
  1220. #ifdef _UNICODE
  1221. char pstrHost[HOSTNAME_SIZE] = { 0 };
  1222. WideCharToMultiByte(CP_UTF8, 0, szHost, -1, pstrHost, sizeof(pstrHost), NULL, NULL );
  1223. #else
  1224. LPCTSTR pstrHost = szHost;
  1225. #endif
  1226. // get address info
  1227. sockaddr_storage addr_store = { 0 };
  1228. addr_store.ss_family = static_cast<short>(nFamily);
  1229. _inet_pton(nFamily, pstrHost, &addr_store);
  1230. const void* addr;
  1231. if (addr_store.ss_family == AF_INET) {
  1232. addr = &((const sockaddr_in*)&addr_store)->sin_addr;
  1233. } else {
  1234. addr = &((const sockaddr_in6*)&addr_store)->sin6_addr;
  1235. }
  1236. if (_inet_ntop(addr_store.ss_family, const_cast<void*>(addr), szAddress, MAX_PATH) != NULL)
  1237. {
  1238. // Unicode conversion
  1239. #ifdef _UNICODE
  1240. return (0 != MultiByteToWideChar(CP_UTF8, 0, szAddress, -1, pszAddress, nSize ));
  1241. #else
  1242. ::StringCbCopyA(pszAddress, nSize, szAddress);
  1243. return true;
  1244. #endif
  1245. }
  1246. else
  1247. SetLastError( WSAGetLastError() );
  1248. }
  1249. }
  1250. else
  1251. SetLastError(ERROR_INVALID_PARAMETER);
  1252. return false;
  1253. }
  1254. /************************************************************************/
  1255. /* 函数:GetAddressInfo[2/29/2016 IT];
  1256. /* 描述:Get IP address info of a host (Supports: IPv4 and IPv6);
  1257. /* 参数:;
  1258. /* [IN] pszHostName:host name or IP address;
  1259. /* [IN] pszServiceName:pszServiceName Network service name (e.g.: "ftp", "telnet") or port number;
  1260. /* [IN] nFamily:address family to use (AF_INET, AF_INET6);
  1261. /* [IN] sockAddr:Socket address to fill in;
  1262. /* 返回:return true if successful;
  1263. /* 注意:;
  1264. /* 示例:;
  1265. /*
  1266. /* 修改:;
  1267. /* 日期:;
  1268. /* 内容:;
  1269. /************************************************************************/
  1270. bool CSocketHandle::GetAddressInfo(LPCTSTR pszHostName, LPCTSTR pszServiceName,int nFamily, SockAddrIn& sockAddr)
  1271. {
  1272. const TCHAR szZERO[] = TEXT("0");
  1273. ADDRINFO aiHints;
  1274. ADDRINFO *aiList = NULL;
  1275. memset(&aiHints, 0, sizeof(aiHints));
  1276. aiHints.ai_flags = AI_ADDRCONFIG; // Jeff.暂时禁掉;
  1277. aiHints.ai_family = static_cast<short>(nFamily);
  1278. TCHAR szLocal[HOSTNAME_SIZE] = { 0 };
  1279. // if no name specified, get local
  1280. if ( NULL == pszHostName || !pszHostName[0])
  1281. {
  1282. GetLocalName(szLocal, HOSTNAME_SIZE);
  1283. pszHostName = szLocal;
  1284. }
  1285. if ( NULL == pszServiceName || !pszServiceName[0])
  1286. {
  1287. pszServiceName = szZERO;
  1288. }
  1289. #ifdef _UNICODE
  1290. char pstrHost[HOSTNAME_SIZE] = { 0 };
  1291. WideCharToMultiByte(CP_UTF8, 0, pszHostName, -1, pstrHost, sizeof(pstrHost), NULL, NULL );
  1292. char pstrService[HOSTNAME_SIZE] = { 0 };
  1293. WideCharToMultiByte(CP_UTF8, 0, pszServiceName, -1, pstrService, sizeof(pstrService), NULL, NULL );
  1294. #else
  1295. LPCTSTR pstrHost = pszHostName;
  1296. LPCTSTR pstrService = pszServiceName;
  1297. #endif
  1298. if ( SOCKET_ERROR != getaddrinfo(pstrHost, pstrService, &aiHints, &aiList) && ( aiList != 0 ))
  1299. {
  1300. ADDRINFO ai = { 0 };
  1301. ai.ai_addr = sockAddr;
  1302. memcpy(ai.ai_addr, aiList->ai_addr, aiList->ai_addrlen);
  1303. freeaddrinfo( aiList );
  1304. return true;
  1305. }
  1306. SetLastError( WSAGetLastError() );
  1307. return false;
  1308. }
  1309. ///////////////////////////////////////////////////////////////////////////////
  1310. // Globals
  1311. ///////////////////////////////////////////////////////////////////////////////
  1312. #if !defined(PLATFORM_HAS_INETFUNC)
  1313. #if 0
  1314. ///////////////////////////////////////////////////////////////////////////////
  1315. // inet_ntop
  1316. const char *_inet_ntop(int af, const void *src, char *dst, size_t cnt)
  1317. {
  1318. if ( dst != NULL)
  1319. {
  1320. dst[0] = 0;
  1321. if (af == AF_INET)
  1322. {
  1323. sockaddr_in in;
  1324. memset(&in, 0, sizeof(in));
  1325. in.sin_family = AF_INET;
  1326. memcpy(&in.sin_addr, src, sizeof(in_addr));
  1327. getnameinfo((sockaddr *)&in, sizeof(sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
  1328. return dst;
  1329. }
  1330. else if (af == AF_INET6)
  1331. {
  1332. sockaddr_in6 in;
  1333. memset(&in, 0, sizeof(in));
  1334. in.sin6_family = AF_INET6;
  1335. memcpy(&in.sin6_addr, src, sizeof(in6_addr));
  1336. getnameinfo((sockaddr *)&in, sizeof(sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
  1337. return dst;
  1338. }
  1339. }
  1340. WSASetLastError(WSA_INVALID_PARAMETER);
  1341. return dst;
  1342. }
  1343. ///////////////////////////////////////////////////////////////////////////////
  1344. // inet_pton
  1345. int _inet_pton(int af, const char *src, void *dst)
  1346. {
  1347. int result = SOCKET_ERROR;
  1348. addrinfo aiHints, *aiList = NULL;
  1349. memset(&aiHints, 0, sizeof(aiHints));
  1350. aiHints.ai_family = af;
  1351. if ( SOCKET_ERROR != getaddrinfo(src, NULL, &aiHints, &aiList) && (aiList != NULL))
  1352. {
  1353. memcpy(dst, aiList->ai_addr, aiList->ai_addrlen);
  1354. freeaddrinfo(aiList);
  1355. result = 0;
  1356. }
  1357. return result;
  1358. }
  1359. #else
  1360. //////////////////////////////////////////////////////////////////////////
  1361. static const char * inet_ntop_v4 (const void *src, char *dst, size_t size)
  1362. {
  1363. const char digits[] = "0123456789";
  1364. int i;
  1365. struct in_addr *addr = (struct in_addr *)src;
  1366. u_long a = ntohl(addr->s_addr);
  1367. const char *orig_dst = dst;
  1368. if (size < INET_ADDRSTRLEN) {
  1369. errno = ENOSPC;
  1370. return NULL;
  1371. }
  1372. for (i = 0; i < 4; ++i) {
  1373. int n = (a >> (24 - i * 8)) & 0xFF;
  1374. int non_zerop = 0;
  1375. if (non_zerop || n / 100 > 0) {
  1376. *dst++ = digits[n / 100];
  1377. n %= 100;
  1378. non_zerop = 1;
  1379. }
  1380. if (non_zerop || n / 10 > 0) {
  1381. *dst++ = digits[n / 10];
  1382. n %= 10;
  1383. non_zerop = 1;
  1384. }
  1385. *dst++ = digits[n];
  1386. if (i != 3)
  1387. *dst++ = '.';
  1388. }
  1389. *dst++ = '\0';
  1390. return orig_dst;
  1391. }
  1392. #ifdef HAVE_IPV6
  1393. static const char * inet_ntop_v6 (const void *src, char *dst, size_t size)
  1394. {
  1395. const char xdigits[] = "0123456789abcdef";
  1396. int i;
  1397. const struct in6_addr *addr = (struct in6_addr *)src;
  1398. const u_char *ptr = addr->s6_addr;
  1399. const char *orig_dst = dst;
  1400. int compressed = 0;
  1401. if (size < INET6_ADDRSTRLEN) {
  1402. errno = ENOSPC;
  1403. return NULL;
  1404. }
  1405. for (i = 0; i < 8; ++i) {
  1406. int non_zerop = 0;
  1407. if (compressed == 0 &&
  1408. ptr[0] == 0 && ptr[1] == 0 &&
  1409. i <= 5 &&
  1410. ptr[2] == 0 && ptr[3] == 0 &&
  1411. ptr[4] == 0 && ptr[5] == 0) {
  1412. compressed = 1;
  1413. if (i == 0)
  1414. *dst++ = ':';
  1415. *dst++ = ':';
  1416. for (ptr += 6, i += 3;
  1417. i < 8 && ptr[0] == 0 && ptr[1] == 0;
  1418. ++i, ptr += 2);
  1419. if (i >= 8)
  1420. break;
  1421. }
  1422. if (non_zerop || (ptr[0] >> 4)) {
  1423. *dst++ = xdigits[ptr[0] >> 4];
  1424. non_zerop = 1;
  1425. }
  1426. if (non_zerop || (ptr[0] & 0x0F)) {
  1427. *dst++ = xdigits[ptr[0] & 0x0F];
  1428. non_zerop = 1;
  1429. }
  1430. if (non_zerop || (ptr[1] >> 4)) {
  1431. *dst++ = xdigits[ptr[1] >> 4];
  1432. non_zerop = 1;
  1433. }
  1434. *dst++ = xdigits[ptr[1] & 0x0F];
  1435. if (i != 7)
  1436. *dst++ = ':';
  1437. ptr += 2;
  1438. }
  1439. *dst++ = '\0';
  1440. return orig_dst;
  1441. }
  1442. #endif /* HAVE_IPV6 */
  1443. const char * _inet_ntop(int af, const void *src, char *dst, size_t size)
  1444. {
  1445. switch (af) {
  1446. case AF_INET :
  1447. return inet_ntop_v4 (src, dst, size);
  1448. #ifdef HAVE_IPV6
  1449. case AF_INET6 :
  1450. return inet_ntop_v6 (src, dst, size);
  1451. #endif
  1452. default :
  1453. //errno = EAFNOSUPPORT;
  1454. return NULL;
  1455. }
  1456. }
  1457. int _inet_pton(int af, const char *csrc, void *dst)
  1458. {
  1459. char * src;
  1460. #ifdef VC60
  1461. if (csrc == NULL || (src = strdup(csrc)) == NULL) {
  1462. #else
  1463. if (csrc == NULL || (src = _strdup(csrc)) == NULL) {
  1464. #endif
  1465. _set_errno( ENOMEM );
  1466. return 0;
  1467. }
  1468. switch (af) {
  1469. case AF_INET:
  1470. {
  1471. struct sockaddr_in si4;
  1472. INT r;
  1473. INT s = sizeof(si4);
  1474. si4.sin_family = AF_INET;
  1475. r = WSAStringToAddress(src, AF_INET, NULL, (LPSOCKADDR) &si4, &s);
  1476. free(src);
  1477. src = NULL;
  1478. if (r == 0) {
  1479. memcpy(dst, &si4.sin_addr, sizeof(si4.sin_addr));
  1480. return 1;
  1481. }
  1482. }
  1483. break;
  1484. case AF_INET6:
  1485. {
  1486. struct sockaddr_in6 si6;
  1487. INT r;
  1488. INT s = sizeof(si6);
  1489. si6.sin6_family = AF_INET6;
  1490. r = WSAStringToAddress(src, AF_INET6, NULL, (LPSOCKADDR) &si6, &s);
  1491. free(src);
  1492. src = NULL;
  1493. if (r == 0) {
  1494. memcpy(dst, &si6.sin6_addr, sizeof(si6.sin6_addr));
  1495. return 1;
  1496. }
  1497. }
  1498. break;
  1499. default:
  1500. _set_errno( ENOSYS/*EAFNOSUPPORT*/ );
  1501. return -1;
  1502. }
  1503. /* the call failed */
  1504. {
  1505. int le = WSAGetLastError();
  1506. if (le == WSAEINVAL)
  1507. return 0;
  1508. _set_errno(le);
  1509. return -1;
  1510. }
  1511. }
  1512. #endif
  1513. #endif