SocketHandle.cpp 48 KB

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