SocketHandle.cpp 44 KB

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