SocketHandle.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650
  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 * 1200; // 3分钟超时 Keep Alive;
  70. klive.keepaliveinterval = 1000 * 300; // 重试间隔为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, false);
  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, bool bIsClient /* = true */)
  1274. {
  1275. const TCHAR szZERO[] = TEXT("0");
  1276. ADDRINFO aiHints;
  1277. ADDRINFO *aiList = NULL;
  1278. memset(&aiHints, 0, sizeof(aiHints));
  1279. if (bIsClient)
  1280. aiHints.ai_flags = AI_ADDRCONFIG; // 查询配置的地址类型(IPv4或IPv6);
  1281. else
  1282. aiHints.ai_flags = AI_PASSIVE; //socket地址用于监听绑定(通常用于服务端bin);
  1283. aiHints.ai_family = nFamily;
  1284. aiHints.ai_protocol = IPPROTO_IP; // Any protocol;
  1285. TCHAR szLocal[HOSTNAME_SIZE] = { 0 };
  1286. // 客户需要获取计算机名;
  1287. if ( bIsClient && (NULL == pszHostName || !pszHostName[0]))
  1288. {
  1289. GetLocalName(szLocal, HOSTNAME_SIZE);
  1290. pszHostName = szLocal;
  1291. }
  1292. if ( NULL == pszServiceName || !pszServiceName[0])
  1293. {
  1294. pszServiceName = szZERO;
  1295. }
  1296. #ifdef _UNICODE
  1297. char pstrHost[HOSTNAME_SIZE] = { 0 };
  1298. WideCharToMultiByte(CP_UTF8, 0, pszHostName, -1, pstrHost, sizeof(pstrHost), NULL, NULL );
  1299. char pstrService[HOSTNAME_SIZE] = { 0 };
  1300. WideCharToMultiByte(CP_UTF8, 0, pszServiceName, -1, pstrService, sizeof(pstrService), NULL, NULL );
  1301. #else
  1302. LPCTSTR pstrHost = pszHostName;
  1303. LPCTSTR pstrService = pszServiceName;
  1304. #endif
  1305. if ( SOCKET_ERROR != getaddrinfo(pstrHost, pstrService, &aiHints, &aiList) && ( aiList != 0 ))
  1306. {
  1307. #if 1
  1308. ADDRINFO *pCur = NULL;
  1309. SOCKADDR_IN *addr = NULL;
  1310. for ( pCur = aiList; pCur != NULL; pCur = aiList->ai_next )
  1311. {
  1312. addr = (SOCKADDR_IN *)pCur->ai_addr;
  1313. }
  1314. #endif
  1315. ADDRINFO ai = { 0 };
  1316. ai.ai_addr = sockAddr;
  1317. memcpy(ai.ai_addr, aiList->ai_addr, aiList->ai_addrlen);
  1318. freeaddrinfo( aiList );
  1319. return true;
  1320. }
  1321. SetLastError( WSAGetLastError() );
  1322. return false;
  1323. }
  1324. ///////////////////////////////////////////////////////////////////////////////
  1325. // Globals
  1326. ///////////////////////////////////////////////////////////////////////////////
  1327. #if !defined(PLATFORM_HAS_INETFUNC)
  1328. ///////////////////////////////////////////////////////////////////////////////
  1329. // inet_ntop
  1330. #if 0
  1331. const char *inet_ntop(int af, const void *src, char *dst, size_t cnt)
  1332. {
  1333. if ( dst != NULL)
  1334. {
  1335. dst[0] = 0;
  1336. if (af == AF_INET)
  1337. {
  1338. sockaddr_in in;
  1339. memset(&in, 0, sizeof(in));
  1340. in.sin_family = AF_INET;
  1341. memcpy(&in.sin_addr, src, sizeof(in_addr));
  1342. getnameinfo((sockaddr *)&in, sizeof(sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
  1343. return dst;
  1344. }
  1345. else if (af == AF_INET6)
  1346. {
  1347. sockaddr_in6 in;
  1348. memset(&in, 0, sizeof(in));
  1349. in.sin6_family = AF_INET6;
  1350. memcpy(&in.sin6_addr, src, sizeof(in6_addr));
  1351. getnameinfo((sockaddr *)&in, sizeof(sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
  1352. return dst;
  1353. }
  1354. }
  1355. WSASetLastError(WSA_INVALID_PARAMETER);
  1356. return dst;
  1357. }
  1358. ///////////////////////////////////////////////////////////////////////////////
  1359. // inet_pton
  1360. int inet_pton(int af, const char *src, void *dst)
  1361. {
  1362. int result = SOCKET_ERROR;
  1363. addrinfo aiHints, *aiList = NULL;
  1364. memset(&aiHints, 0, sizeof(aiHints));
  1365. aiHints.ai_family = af;
  1366. if ( SOCKET_ERROR != getaddrinfo(src, NULL, &aiHints, &aiList) && (aiList != NULL))
  1367. {
  1368. memcpy(dst, aiList->ai_addr, aiList->ai_addrlen);
  1369. freeaddrinfo(aiList);
  1370. result = 0;
  1371. }
  1372. return result;
  1373. }
  1374. #else
  1375. //////////////////////////////////////////////////////////////////////////
  1376. static const char * inet_ntop_v4 (const void *src, char *dst, size_t size)
  1377. {
  1378. const char digits[] = "0123456789";
  1379. int i;
  1380. struct in_addr *addr = (struct in_addr *)src;
  1381. u_long a = ntohl(addr->s_addr);
  1382. const char *orig_dst = dst;
  1383. if (size < INET_ADDRSTRLEN) {
  1384. errno = ENOSPC;
  1385. return NULL;
  1386. }
  1387. for (i = 0; i < 4; ++i) {
  1388. int n = (a >> (24 - i * 8)) & 0xFF;
  1389. int non_zerop = 0;
  1390. if (non_zerop || n / 100 > 0) {
  1391. *dst++ = digits[n / 100];
  1392. n %= 100;
  1393. non_zerop = 1;
  1394. }
  1395. if (non_zerop || n / 10 > 0) {
  1396. *dst++ = digits[n / 10];
  1397. n %= 10;
  1398. non_zerop = 1;
  1399. }
  1400. *dst++ = digits[n];
  1401. if (i != 3)
  1402. *dst++ = '.';
  1403. }
  1404. *dst++ = '\0';
  1405. return orig_dst;
  1406. }
  1407. #ifdef HAVE_IPV6
  1408. static const char * inet_ntop_v6 (const void *src, char *dst, size_t size)
  1409. {
  1410. const char xdigits[] = "0123456789abcdef";
  1411. int i;
  1412. const struct in6_addr *addr = (struct in6_addr *)src;
  1413. const u_char *ptr = addr->s6_addr;
  1414. const char *orig_dst = dst;
  1415. int compressed = 0;
  1416. if (size < INET6_ADDRSTRLEN) {
  1417. errno = ENOSPC;
  1418. return NULL;
  1419. }
  1420. for (i = 0; i < 8; ++i) {
  1421. int non_zerop = 0;
  1422. if (compressed == 0 &&
  1423. ptr[0] == 0 && ptr[1] == 0 &&
  1424. i <= 5 &&
  1425. ptr[2] == 0 && ptr[3] == 0 &&
  1426. ptr[4] == 0 && ptr[5] == 0) {
  1427. compressed = 1;
  1428. if (i == 0)
  1429. *dst++ = ':';
  1430. *dst++ = ':';
  1431. for (ptr += 6, i += 3;
  1432. i < 8 && ptr[0] == 0 && ptr[1] == 0;
  1433. ++i, ptr += 2);
  1434. if (i >= 8)
  1435. break;
  1436. }
  1437. if (non_zerop || (ptr[0] >> 4)) {
  1438. *dst++ = xdigits[ptr[0] >> 4];
  1439. non_zerop = 1;
  1440. }
  1441. if (non_zerop || (ptr[0] & 0x0F)) {
  1442. *dst++ = xdigits[ptr[0] & 0x0F];
  1443. non_zerop = 1;
  1444. }
  1445. if (non_zerop || (ptr[1] >> 4)) {
  1446. *dst++ = xdigits[ptr[1] >> 4];
  1447. non_zerop = 1;
  1448. }
  1449. *dst++ = xdigits[ptr[1] & 0x0F];
  1450. if (i != 7)
  1451. *dst++ = ':';
  1452. ptr += 2;
  1453. }
  1454. *dst++ = '\0';
  1455. return orig_dst;
  1456. }
  1457. #endif /* HAVE_IPV6 */
  1458. const char * inet_ntop(int af, const void *src, char *dst, size_t size)
  1459. {
  1460. switch (af) {
  1461. case AF_INET :
  1462. return inet_ntop_v4 (src, dst, size);
  1463. #ifdef HAVE_IPV6
  1464. case AF_INET6 :
  1465. return inet_ntop_v6 (src, dst, size);
  1466. #endif
  1467. default :
  1468. //errno = EAFNOSUPPORT;
  1469. return NULL;
  1470. }
  1471. }
  1472. int inet_pton(int af, const char *csrc, void *dst)
  1473. {
  1474. char * src;
  1475. if (csrc == NULL || (src = strdup(csrc)) == NULL) {
  1476. _set_errno( ENOMEM );
  1477. return 0;
  1478. }
  1479. switch (af) {
  1480. case AF_INET:
  1481. {
  1482. struct sockaddr_in si4;
  1483. INT r;
  1484. INT s = sizeof(si4);
  1485. si4.sin_family = AF_INET;
  1486. r = WSAStringToAddress(src, AF_INET, NULL, (LPSOCKADDR) &si4, &s);
  1487. free(src);
  1488. src = NULL;
  1489. if (r == 0) {
  1490. memcpy(dst, &si4.sin_addr, sizeof(si4.sin_addr));
  1491. return 1;
  1492. }
  1493. }
  1494. break;
  1495. case AF_INET6:
  1496. {
  1497. struct sockaddr_in6 si6;
  1498. INT r;
  1499. INT s = sizeof(si6);
  1500. si6.sin6_family = AF_INET6;
  1501. r = WSAStringToAddress(src, AF_INET6, NULL, (LPSOCKADDR) &si6, &s);
  1502. free(src);
  1503. src = NULL;
  1504. if (r == 0) {
  1505. memcpy(dst, &si6.sin6_addr, sizeof(si6.sin6_addr));
  1506. return 1;
  1507. }
  1508. }
  1509. break;
  1510. default:
  1511. _set_errno( ENOSYS/*EAFNOSUPPORT*/ );
  1512. return -1;
  1513. }
  1514. /* the call failed */
  1515. {
  1516. int le = WSAGetLastError();
  1517. if (le == WSAEINVAL)
  1518. return 0;
  1519. _set_errno(le);
  1520. return -1;
  1521. }
  1522. }
  1523. #endif
  1524. #endif