123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650 |
- #include "stdafx.h"
- #ifdef WIN32
- #include <stdlib.h>
- #ifndef UNDER_CE
- #include <crtdbg.h>
- #endif
- #include <strsafe.h>
- #endif
- #include "SocketHandle.h"
- // Jeff.add.
- //#include "Wspiapi.h"
- //#include "Ws2tcpip.h"
- #include <MSTcpIP.h>
- #ifndef BUFFER_SIZE
- #define BUFFER_SIZE 64*1024
- #endif
- #ifndef SOCKHANDLE_TTL
- #define SOCKHANDLE_TTL 5
- #endif
- #ifndef SOCKHANDLE_HOPS
- #define SOCKHANDLE_HOPS 10
- #endif
- #define HOSTNAME_SIZE MAX_PATH
- #define STRING_LENGTH 40
- #if !defined(PLATFORM_HAS_INETFUNC)
- const char *inet_ntop(int af, const void *src, char *dst, size_t cnt);
- int inet_pton(int af, const char *src, void *dst);
- #endif
- #ifdef WIN32
- #ifndef UNDER_CE
- #pragma comment(lib, "ws2_32.lib")
- #else
- #pragma comment(lib, "Ws2.lib")
- #endif
- #endif
- #if 1
- typedef struct STcpKeepAlive2
- {
- DWORD onoff;
- DWORD keepalivetime;
- DWORD keepaliveinterval;
- }TCP_KEEP_ALIVE2;
- /************************************************************************/
- /* 函数:SetKeepLive[2/29/2016 IT];
- /* 描述:设置TCP连接鲜活时间;
- /* 参数:;
- /* [IN] Socket:要设置的客户端SOCKET;
- /* 返回:设置成功返回TRUE;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- BOOL SetKeepLive(IN SOCKET &Socket)
- {
- const BYTE chOpt = 1; // True;
- // Set KeepAlive 开启保活机制, 防止服务端产生死连接;
- if (setsockopt(Socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&chOpt, sizeof(chOpt)) == SOCKET_ERROR)
- {
- printf("设置客户端鲜活机制失败1\n\n");
- return FALSE;
- }
- // 设置超时详细信息;
- BYTE byRet[5] = {0};
- TCP_KEEP_ALIVE2 klive;
- klive.onoff = 1; // 启用保活;
- klive.keepalivetime = 1000 * 1200; // 3分钟超时 Keep Alive;
- klive.keepaliveinterval = 1000 * 300; // 重试间隔为5秒 Resend if No-Reply;
- INT nResult =
- WSAIoctl
- (
- Socket,
- SIO_KEEPALIVE_VALS,
- &klive,
- sizeof(TCP_KEEP_ALIVE2),
- NULL,
- 0,
- (unsigned long *)&byRet,
- 0,
- NULL
- );
- if ( nResult == SOCKET_ERROR )
- {
- printf("设置客户端鲜活机制失败2\n\n");
- return FALSE;
- }
- return TRUE;
- }
- #endif
- CSocketHandle::CSocketHandle(): m_hSocket(INVALID_SOCKET)
- {
- m_npendingSize = 0;
- memset(m_szpendingbuf,0,SOCKET_BUFFSIZE);
- }
- CSocketHandle::~CSocketHandle()
- {
- Close();
- }
- bool CSocketHandle::IsOpen() const
- {
- return ( INVALID_SOCKET != m_hSocket );
- }
- SOCKET CSocketHandle::GetSocket() const
- {
- return m_hSocket;
- }
- /************************************************************************/
- /* 函数:GetSocketType[2/29/2016 IT];
- /* 描述:获取套接字类型;
- /* 参数:;
- /* 返回:返回-1表示不是一个有效的套接字;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- int CSocketHandle::GetSocketType() const
- {
- int type = -1;
- if ( INVALID_SOCKET != m_hSocket ) {
- socklen_t optlen = sizeof(int);
- if ( getsockopt(GetSocket(), SOL_SOCKET, SO_TYPE, reinterpret_cast<char*>(&type),&optlen) == SOCKET_ERROR)
- {
- SetLastError( WSAGetLastError() );
- }
- }
- return type;
- }
- /************************************************************************/
- /* 函数:Attach[2/29/2016 IT];
- /* 描述:附加一个SOCKET句柄,使用Detach函数或Close函数来释放句柄;
- /* 参数:;
- /* [IN] sock:要附加到类中的套接字句柄;
- /* 返回:成功返回TRUE;
- /* 注意:函数有可能失败,当要附加的套接字是一个无效值或该值已在使用时;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::Attach(IN SOCKET sock)
- {
- if ( INVALID_SOCKET == m_hSocket )
- {
- m_hSocket = sock;
- return true;
- }
- return false;
- }
- /************************************************************************/
- /* 函数:Detach[2/29/2016 IT];
- /* 描述:把套接字从类对象中分离出来;
- /* 参数:无;
- /* 返回:返回前面附加的套接字句柄或INVALID_SOCKET;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- SOCKET CSocketHandle::Detach()
- {
- SOCKET sock = m_hSocket;
- ::InterlockedExchange(reinterpret_cast<long*>(&m_hSocket), INVALID_SOCKET);
- return sock;
- }
- /************************************************************************/
- /* 函数:GetSockName[2/29/2016 IT];
- /* 描述:获取套接字名(本地地址);
- /* 参数:;
- /* [OUT] saddr_in:连接成功时返回的当前本地地址和端口号;
- /* 返回:成功返回TRUE;
- /* 注意:使用前必须调用InitLibrary函数;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::GetSockName(OUT SockAddrIn& saddr_in) const
- {
- _ASSERTE( IsOpen() );
- if (IsOpen()) {
- socklen_t namelen = (socklen_t)saddr_in.Size();
- if (SOCKET_ERROR != getsockname(GetSocket(), saddr_in, &namelen))
- {
- return true;
- }
- SetLastError( WSAGetLastError() );
- }
- return false;
- }
- /************************************************************************/
- /* 函数:GetPeerName[2/29/2016 IT];
- /* 描述:获取点对点的套接接名(获取Peer地址);;
- /* 参数:;
- /* [OUT] saddr_in: peer address and port (use only with TCP or client mode UDP);
- /* 返回:成功返回TRUE;
- /* 注意:使用前必须调用InitLibrary函数;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::GetPeerName(OUT SockAddrIn& saddr_in) const
- {
- //_ASSERTE( IsOpen() );
- if (IsOpen()) {
- socklen_t namelen = (socklen_t)saddr_in.Size();
- if (SOCKET_ERROR != getpeername(GetSocket(), saddr_in, &namelen))
- {
- return true;
- }
- SetLastError( WSAGetLastError() );
- }
- return false;
- }
- /************************************************************************/
- /* 函数:Close[2/29/2016 IT];
- /* 描述:关闭套接字;
- /* 参数:;
- /* 返回:void;
- /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void CSocketHandle::Close()
- {
- if ( IsOpen() )
- {
- ShutdownConnection(static_cast<SOCKET>(::InterlockedExchange((LONG*)&m_hSocket, INVALID_SOCKET)));
- }
- }
- /************************************************************************/
- /* 函数:AddMembership[2/29/2016 IT];
- /* 描述:添加多播地址;
- /* 参数:;
- /* [IN] pszIPAddr:多播IP组;
- /* [IN] pszNIC:IP地址接口(多张网卡时,某一网卡序列号);
- /* 返回:成功返回TRUE;
- /* 注意:关联InitLibrary函数;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::AddMembership(IN LPCTSTR pszIPAddr, IN LPCTSTR pszNIC)
- {
- _ASSERTE( IsOpen() );
- if ( IsOpen() )
- {
- int nType = 0;
- socklen_t nOptLen = sizeof(int);
- if ( SOCKET_ERROR != getsockopt(m_hSocket, SOL_SOCKET, SO_TYPE, (char*)&nType, &nOptLen))
- {
- if ( nType == SOCK_DGRAM )
- {
- // Setup interface for multicast traffic
- SockAddrIn mcastAddr;
- if (GetAddressInfo(pszIPAddr, NULL, AF_UNSPEC, mcastAddr))
- {
- SockAddrIn interfAddr;
- GetAddressInfo(pszNIC, NULL, mcastAddr.ss_family, interfAddr);
- if ( mcastAddr.ss_family == AF_INET )
- {
- int nTTL = SOCKHANDLE_TTL;
- if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&nTTL, sizeof(nTTL)))
- {
- ULONG ulNIC = interfAddr.GetIPAddr();
- if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IP, IP_MULTICAST_IF,(char *) &ulNIC, sizeof(ulNIC)))
- {
- ip_mreq mreq = { 0 };
- mreq.imr_multiaddr.s_addr = mcastAddr.GetIPAddr();
- mreq.imr_interface.s_addr = ulNIC;
- if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)))
- {
- return true;
- }
- }
- }
- }
- else if ( mcastAddr.ss_family == AF_INET6 )
- {
- int nTTL = SOCKHANDLE_HOPS;
- if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&nTTL, sizeof(nTTL)))
- {
- ipv6_mreq mreq6 = { 0 };
- IN6_ADDR mcin6 = ((sockaddr_in6*)&mcastAddr)->sin6_addr;
- memcpy(&(mreq6.ipv6mr_multiaddr), &mcin6, sizeof(IN6_ADDR));
- if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char*)&mreq6, sizeof(mreq6)))
- {
- return true;
- }
- }
- }
- else
- {
- // invalid socket option
- WSASetLastError(WSAENOPROTOOPT);
- }
- }
- }
- else
- {
- // invalid socket option
- WSASetLastError(WSAENOPROTOOPT);
- }
- }
- SetLastError( WSAGetLastError() );
- }
- return false;
- }
- /************************************************************************/
- /* 函数:DropMembership[2/29/2016 IT];
- /* 描述:移除多播地址;
- /* 参数:;
- /* [IN] pszIPAddr:多播IP组;
- /* [IN] pszNIC:IP地址接口(多张网卡时,某一网卡序列号);
- /* 返回:成功返回TRUE;
- /* 注意:关联InitLibrary函数;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::DropMembership(LPCTSTR pszIPAddr, LPCTSTR pszNIC)
- {
- _ASSERTE( IsOpen() );
- if ( IsOpen() )
- {
- int nType = 0;
- socklen_t nOptLen = sizeof(int);
- if ( SOCKET_ERROR != getsockopt(m_hSocket, SOL_SOCKET, SO_TYPE, (char*)&nType, &nOptLen))
- {
- if ( nType == SOCK_DGRAM )
- {
- SockAddrIn mcastAddr;
- if (GetAddressInfo(pszIPAddr, NULL, AF_UNSPEC, mcastAddr))
- {
- SockAddrIn interfAddr;
- GetAddressInfo(pszNIC, NULL, mcastAddr.ss_family, interfAddr);
- if ( mcastAddr.ss_family == AF_INET )
- {
- ip_mreq mreq;
- mreq.imr_multiaddr.s_addr = mcastAddr.GetIPAddr();
- mreq.imr_interface.s_addr = interfAddr.GetIPAddr();;
- if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)))
- {
- return true;
- }
- }
- else if ( mcastAddr.ss_family == AF_INET6 )
- {
- ipv6_mreq mreq6 = { 0 };
- IN6_ADDR mcin6 = ((sockaddr_in6*)&mcastAddr)->sin6_addr;
- memcpy(&(mreq6.ipv6mr_multiaddr), &mcin6, sizeof(IN6_ADDR));
- if ( SOCKET_ERROR != setsockopt(m_hSocket, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (const char*)&mreq6, sizeof(mreq6)))
- {
- return true;
- }
- }
- else
- {
- // invalid socket option
- WSASetLastError(WSAENOPROTOOPT);
- }
- }
- }
- else
- {
- // invalid socket option
- WSASetLastError(WSAENOPROTOOPT);
- }
- }
- SetLastError( WSAGetLastError() );
- }
- return false;
- }
- /************************************************************************/
- /* 函数:CreateSocket[2/29/2016 IT];
- /* 描述:创建服务端套接字;
- /* 参数:;
- /* [IN] pszHostName:主机名或网卡适配器地址;
- /* [IN] pszServiceName:网络服务名或者IP端口号;
- /* [IN] nFamily:要用的地址协议簇类型(IPV4或IPV6);
- /* [IN] nType:要创建的套接字类型(SOCK_STREAM 或 SOCK_DGRAM);
- /* [IN] uOptions:附加选项(SO_BROADCAST,SO_REUSEADDR) ;
- /* 返回:成功返回TRUE;
- /* 注意:使用WSAGetLastError()函数获取最后的错误,关联函数InitLibrary, ConnectTo, IsOpen;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::CreateSocket(IN LPCTSTR pszHostName, IN LPCTSTR pszServiceName, IN int nFamily, IN int nType, IN UINT uOptions /* = 0 */)
- {
- // Socket is already opened
- if ( IsOpen() ) {
- SetLastError(ERROR_ACCESS_DENIED);
- return false;
- }
- // Create a Socket that is bound to a specific service provider
- // nFamily: (AF_INET, AF_INET6)
- // nType: (SOCK_STREAM, SOCK_DGRAM)
- #ifdef SOCKHANDLE_USE_OVERLAPPED
- SOCKET sock = WSASocket(nFamily, nType, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
- #else
- SOCKET sock = socket(nFamily, nType, IPPROTO_IP);
- #endif
- if (INVALID_SOCKET != sock)
- {
- if (uOptions & SO_REUSEADDR)
- {
- // Inform Windows Sockets provider that a bind on a socket should not be disallowed
- // because the desired address is already in use by another socket
- BOOL optval = TRUE;
- if ( SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof( BOOL ) ) )
- {
- SetLastError( WSAGetLastError() );
- closesocket( sock );
- return false;
- }
- }
- if (nType == SOCK_DGRAM)
- {
- if ((uOptions & SO_BROADCAST) && (nFamily == AF_INET))
- {
- // Inform Windows Sockets provider that broadcast messages are allowed
- BOOL optval = TRUE;
- if ( SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (char *) &optval, sizeof( BOOL ) ) )
- {
- SetLastError( WSAGetLastError() );
- closesocket( sock );
- return false;
- }
- }
- #ifdef SOCKHANDLE_CONFIGBUF
- // configure buffer size
- socklen_t rcvbuf = BUFFER_SIZE;
- if ( SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_RCVBUF, (char *) &rcvbuf, sizeof( int ) ) )
- {
- SetLastError( WSAGetLastError() );
- closesocket( sock );
- return false;
- }
- #endif
- }
- // Associate a local address with the socket
- SockAddrIn sockAddr;
- sockAddr.CreateFrom(pszHostName, pszServiceName, nFamily, false);
- if ( SOCKET_ERROR == bind(sock, sockAddr, (int)sockAddr.Size()))
- {
- SetLastError( WSAGetLastError() );
- closesocket( sock );
- return false;
- }
- // Listen to the socket, only valid for connection socket (TCP)
- if (SOCK_STREAM == nType)
- {
- if ( SOCKET_ERROR == listen(sock, SOMAXCONN))
- {
- SetLastError( WSAGetLastError() );
- closesocket( sock );
- return false;
- }
- }
- // Success, now we may save this socket
- m_hSocket = sock;
- }
- return (INVALID_SOCKET != sock);
- }
- /************************************************************************/
- /* 函数:ConnectTo[2/29/2016 IT];
- /* 描述:客户端连接服务端;
- /* 参数:;
- /* [IN] pszHostName:Hostname or NIC address;
- /* [IN] pszRemote:Remote network address;
- /* [IN] pszServiceName:Network service name or port number;
- /* [IN] nFamily:address family to use (AF_INET, AF_INET6);
- /* [IN] nType:type of socket to create (SOCK_STREAM, SOCK_DGRAM);
- /* 返回:return true if successful, otherwise false (call WSAGetLastError() to retrieve latest error);
- /* 注意:关联函数InitLibrary, CreateSocket, IsOpen;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::ConnectTo(IN LPCTSTR pszHostName, IN LPCTSTR pszRemote, IN LPCTSTR pszServiceName, IN int nFamily, IN int nType)
- {
- // Socket is already opened
- if ( IsOpen() ) {
- SetLastError(ERROR_ACCESS_DENIED);
- return false;
- }
- // Create a Socket that is bound to a specific service provider
- // nFamily: (AF_INET, AF_INET6)
- // nType: (SOCK_STREAM, SOCK_DGRAM)
- #ifdef SOCKHANDLE_USE_OVERLAPPED
- SOCKET sock = WSASocket(nFamily, nType, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
- #else
- SOCKET sock = socket(nFamily, nType, IPPROTO_IP);
- #endif
- if (INVALID_SOCKET != sock)
- {
- // Associate a local address with the socket but let provider assign a port number
- SockAddrIn sockAddr;
- if (false == sockAddr.CreateFrom(pszHostName, TEXT("0"), nFamily))
- {
- SetLastError( WSAGetLastError() );
- closesocket( sock );
- return false;
- }
- if ( SOCKET_ERROR == bind(sock, sockAddr, (int)sockAddr.Size()))
- {
- SetLastError( WSAGetLastError() );
- closesocket( sock );
- return false;
- }
- #ifdef SOCKHANDLE_CONFIGBUF
- if (nType == SOCK_DGRAM)
- {
- // configure buffer size
- socklen_t rcvbuf = BUFFER_SIZE;
- if ( SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_RCVBUF, (char *) &rcvbuf, sizeof( int ) ) )
- {
- SetLastError( WSAGetLastError() );
- closesocket( sock );
- return false;
- }
- }
- #endif
- // Now get destination address & port
- sockAddr.CreateFrom( pszRemote, pszServiceName, nFamily );
- // try to connect - if fail, server not ready
- if (SOCKET_ERROR == connect( sock, sockAddr, (int)sockAddr.Size()))
- {
- SetLastError( WSAGetLastError() );
- closesocket( sock );
- return false;
- }
- // Success, now we may save this socket
- m_hSocket = sock;
- }
- return (INVALID_SOCKET != sock);
- }
- /************************************************************************/
- /* 函数:Read[2/29/2016 IT];
- /* 描述:从套接字中读取内容;
- /* 参数:;
- /* [OUT] lpBuffer:Buffer to receive data;
- /* [IN] dwSize:Size of buffer in bytes;
- /* [IN] lpAddrIn:Peer address for UDP - this must be NULL for TCP;
- /* [IN] dwTimeout:Read timeout in milliseconds;
- /* 返回:return number of bytes read or (-1L) if fail;
- /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, Write, WriteEx;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- DWORD CSocketHandle::Read(OUT LPBYTE lpBuffer, IN DWORD dwSize, IN LPSOCKADDR lpAddrIn /* = NULL */, IN DWORD dwTimeout /* = INFINITE */)
- {
- _ASSERTE( IsOpen() );
- _ASSERTE( lpBuffer != NULL );
- if (!IsOpen() || lpBuffer == NULL || dwSize < 1L)
- return (DWORD)-1L;
- fd_set fdRead = { 0 };
- TIMEVAL stTime;
- TIMEVAL *pstTime = NULL;
- if ( INFINITE != dwTimeout ) {
- stTime.tv_sec = dwTimeout/1000;
- stTime.tv_usec = (dwTimeout%1000)*1000;
- pstTime = &stTime;
- }
- SOCKET s = GetSocket();
- // Set Descriptor
- FD_SET( s, &fdRead );
- // Select function set read timeout
- DWORD dwBytesRead = 0L;
- int res = 1;
- if ( pstTime != NULL )
- res = select((int)s, &fdRead, NULL, NULL, pstTime );
- if ( res > 0)
- {
- if (lpAddrIn)
- {
- // UDP
- socklen_t fromlen = sizeof(SOCKADDR_STORAGE);
- res = recvfrom(s, reinterpret_cast<LPSTR>(lpBuffer), dwSize, 0, lpAddrIn, &fromlen);
- }
- else
- {
- // TCP
- res = recv(s, reinterpret_cast<LPSTR>(lpBuffer), dwSize, 0);
- }
- if ( res == 0 ) {
- WSASetLastError(WSAECONNRESET);
- res = SOCKET_ERROR;
- }
- }
- if ( res == SOCKET_ERROR )
- {
- SetLastError( WSAGetLastError() );
- }
- dwBytesRead = (DWORD)((res >= 0)?(res) : (-1));
- return dwBytesRead;
- }
- #ifdef WIN32
- /************************************************************************/
- /* 函数:ReadEx[2/29/2016 IT];
- /* 描述:从套接字读取内容,异步模式(asynchronous mode);
- /* 参数:;
- /* [OUT] lpBuffer:Buffer to receive data;
- /* [IN] dwSize:Size of buffer in bytes;
- /* [IN] lpAddrIn:SockAddrIn for UDP - this must be NULL for TCP;
- /* [IN] lpOverlapped:Windows Overlapped structure (required);
- /* [IN] lpCompletionRoutine:Winsock Completion routine (required);
- /* 返回:return number of bytes read, overlapped operation is pending or (-1L) if fail;
- /* 注意:关联函数 InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, Write, WriteEx, IOControl, GetTransferOverlappedResult;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- DWORD CSocketHandle::ReadEx(OUT LPBYTE lpBuffer, IN DWORD dwSize, IN LPSOCKADDR lpAddrIn, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSACOMPLETIONROUTINE lpCompletionRoutine)
- {
- _ASSERTE( IsOpen() );
- _ASSERTE( lpBuffer != NULL );
- if (!IsOpen() || lpBuffer == NULL || dwSize < 1L)
- return (DWORD)-1L;
- SOCKET s = GetSocket();
- // Send message to peer
- WSABUF wsabuf;
- wsabuf.buf = (char FAR*)lpBuffer;
- wsabuf.len = dwSize;
- // Select function set read timeout
- DWORD dwBytesRead = 0L;
- DWORD dwFlags = 0L;
- int res = 0;
- if (lpAddrIn)
- {
- // UDP
- socklen_t fromlen = sizeof(SOCKADDR_STORAGE);
- res = WSARecvFrom( s, &wsabuf, 1, &dwBytesRead, &dwFlags, lpAddrIn, &fromlen, lpOverlapped, lpCompletionRoutine);
- }
- else
- {
- // TCP
- res = WSARecv( s, &wsabuf, 1, &dwBytesRead, &dwFlags, lpOverlapped, lpCompletionRoutine);
- }
- if ( res == SOCKET_ERROR )
- {
- res = WSAGetLastError();
- if ( res != WSA_IO_PENDING )
- {
- dwBytesRead = (DWORD)-1L;
- SetLastError( res );
- }
- }
- return dwBytesRead;
- }
- #endif
- /************************************************************************/
- /* 函数:Write[2/29/2016 IT];
- /* 描述:向目标套接字发送内容;
- /* 参数:;
- /* [IN] lpBuffer:Buffer to send;
- /* [IN] dwCount:Number of bytes to send;
- /* [IN] lpAddrIn:Peer address for UDP - this must be NULL for TCP;
- /* [IN] dwTimeout:Write timeout in milliseconds;
- /* 返回:return number of bytes sent or (-1L) if fail;
- /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, ReadEx, WriteEx;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- DWORD CSocketHandle::Write(IN const LPBYTE lpBuffer, IN DWORD dwCount, IN const LPSOCKADDR lpAddrIn /* = NULL */, IN DWORD dwTimeout /* = INFINITE */)
- {
- _ASSERTE( IsOpen() );
- _ASSERTE( NULL != lpBuffer );
- // validate params
- if (!IsOpen() || NULL == lpBuffer)
- return (DWORD)-1L;
- fd_set fdWrite = { 0 };
- TIMEVAL stTime;
- TIMEVAL *pstTime = NULL;
- if ( INFINITE != dwTimeout ) {
- stTime.tv_sec = dwTimeout/1000;
- stTime.tv_usec = (dwTimeout%1000)*1000;
- pstTime = &stTime;
- }
- SOCKET s = GetSocket();
- // Set Descriptor
- FD_SET( s, &fdWrite );
- // Select function set write timeout
- DWORD dwBytesWritten = 0L;
- int res = 1;
- if ( pstTime != NULL )
- {
- res = select((int)s, NULL, &fdWrite, NULL, pstTime );
- }
- if ( res > 0)
- {
- // Send message to peer
- if (lpAddrIn)
- {
- // UDP
- res = sendto( s, reinterpret_cast<LPCSTR>(lpBuffer), dwCount, 0, lpAddrIn, sizeof(SOCKADDR_STORAGE));
- }
- else
- {
- // TCP
- res = send( s, reinterpret_cast<LPCSTR>(lpBuffer), dwCount, 0);
- }
- }
- if ( res == SOCKET_ERROR )
- {
- SetLastError( WSAGetLastError() );
- }
- dwBytesWritten = (DWORD)((res >= 0)?(res) : (-1));
- return dwBytesWritten;
- }
- #ifdef WIN32
- /************************************************************************/
- /* 函数:WriteEx[2/29/2016 IT];
- /* 描述:向目标套接字发送内容,异步模式(asynchronous mode);
- /* 参数:;
- /* [IN] lpBuffer:Buffer to send;
- /* [IN] dwCount:Number of bytes to send;
- /* [IN] lpAddrIn:SockAddrIn for UDP - this must be NULL for TCP;
- /* [IN] lpOverlapped:Windows Overlapped structure (required);
- /* [IN] lpCompletionRoutine:Winsock Completion routine (required);
- /* 返回:return number of bytes read, overlapped operation is pending or (-1L) if fail;
- /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, Read, ReadEx, Write, IOControl, GetTransferOverlappedResult;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- DWORD CSocketHandle::WriteEx(IN const LPBYTE lpBuffer, IN DWORD dwCount, IN const LPSOCKADDR lpAddrIn, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSACOMPLETIONROUTINE lpCompletionRoutine)
- {
- _ASSERTE( IsOpen() );
- _ASSERTE( NULL != lpBuffer );
- // validate params
- if (!IsOpen() || NULL == lpBuffer)
- return (DWORD)-1L;
- SOCKET s = GetSocket();
- // Select function set write timeout
- DWORD dwBytesWritten = 0L;
- int res = 0;
- // Send message to peer
- WSABUF wsabuf;
- wsabuf.buf = (char FAR*) lpBuffer;
- wsabuf.len = dwCount;
- if (lpAddrIn)
- {
- // UDP
- res = WSASendTo( s, &wsabuf, 1, &dwBytesWritten, 0, lpAddrIn, sizeof(SOCKADDR_STORAGE),
- lpOverlapped, lpCompletionRoutine);
- }
- else // TCP
- res = WSASend( s, &wsabuf, 1, &dwBytesWritten, 0, lpOverlapped, lpCompletionRoutine);
- if ( res == SOCKET_ERROR )
- {
- res = WSAGetLastError();
- if ( res != WSA_IO_PENDING )
- {
- dwBytesWritten = (DWORD)-1L;
- SetLastError( res );
- }
- }
- return dwBytesWritten;
- }
- #endif
- #ifdef WIN32
- /************************************************************************/
- /* 函数:IOControl[2/29/2016 IT];
- /* 描述:Control the mode of a socket (asynchronous mode);
- /* 参数:;
- /* [IN] dwIoCode:Control code of operation to perform;
- /* [IN] lpInBuffer:Pointer to the input buffer;
- /* [IN] cbInBuffer:Size of the input buffer, in bytes;
- /* [IN] lpOutBuffer:Pointer to the output buffer;
- /* [IN] cbOutBuffer:Size of the output buffer, in bytes;
- /* [IN] lpcbBytesReturned:Pointer to actual number of bytes of output;
- /* [IN] lpOverlapped:Winsock Overlapped structure;
- /* [IN] lpCompletionRoutine:Winsock Completion routine;
- /* 返回:return true if successful, otherwise false (call WSAGetLastError() to retrieve latest error);
- /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, WriteEx, GetTransferOverlappedResult;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::IOControl(
- IN DWORD dwIoCode,
- IN LPBYTE lpInBuffer,
- IN DWORD cbInBuffer,
- IN LPBYTE lpOutBuffer,
- IN DWORD cbOutBuffer,
- IN LPDWORD lpcbBytesReturned,
- IN LPWSAOVERLAPPED lpOverlapped,
- IN LPWSACOMPLETIONROUTINE lpCompletionRoutine )
- {
- _ASSERTE( IsOpen() );
- // validate params
- if ( !IsOpen() ) {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
- int res;
- SOCKET s = GetSocket();
- res = WSAIoctl(s, dwIoCode, lpInBuffer, cbInBuffer, lpOutBuffer, cbOutBuffer,
- lpcbBytesReturned, lpOverlapped, lpCompletionRoutine);
- if ( res == SOCKET_ERROR )
- {
- SetLastError( WSAGetLastError() );
- }
- return ( res != SOCKET_ERROR );
- }
- /************************************************************************/
- /* 函数:GetTransferOverlappedResult[2/29/2016 IT];
- /* 描述:Get Overlapped result (asynchronous mode);
- /* 参数:;
- /* [IN] lpOverlapped:Windows Overlapped structure (required);
- /* [IN] lpcbTransfer:Pointer to get number of bytes transferred;
- /* [IN] bWait:Force wait for overlapped operation to complete;
- /* [IN] lpdwFlags:Optional flags (see MSDN on WSARecv API);
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:成功返回TRUE;
- /* 注意:关联函数InitLibrary, CreateSocket, ConnectTo, IsOpen, ReadEx, WriteEx, IOControl;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::GetTransferOverlappedResult(IN LPWSAOVERLAPPED lpOverlapped, IN LPDWORD lpcbTransfer, IN bool bWait /* = true */, IN LPDWORD lpdwFlags /* = 0 */)
- {
- _ASSERTE( IsOpen() );
- _ASSERTE( NULL != lpOverlapped );
- // validate params
- if (!IsOpen() || NULL == lpOverlapped) {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
- SOCKET s = GetSocket();
- DWORD dwFlags = 0;
- if ( lpdwFlags == NULL )
- lpdwFlags = &dwFlags;
- BOOL bRet = WSAGetOverlappedResult( s, lpOverlapped, lpcbTransfer, bWait, lpdwFlags );
- if ( !bRet )
- {
- SetLastError( WSAGetLastError() );
- }
- return (bRet != FALSE);
- }
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- // Utility functions
- /************************************************************************/
- /* 函数:InitLibrary[2/29/2016 IT];
- /* 描述:Initialize Winsock library. This function calls WSAStartup;
- /* 参数:;
- /* [IN] wVersion:Winsock version use MAKEWORD macro if possible (e.g.: MAKEWORD(2,2));
- /* 返回:return true if successful;
- /* 注意:关联ReleaseLibrary;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::InitLibrary(IN WORD wVersion)
- {
- #ifdef WIN32
- WSADATA WSAData = { 0 };
- return ( 0 == WSAStartup( wVersion, &WSAData ) );
- #else
- return true;
- #endif
- }
- /************************************************************************/
- /* 函数:ReleaseLibrary[2/29/2016 IT];
- /* 描述:Release Winsock library;
- /* 参数:;
- /* 返回:return true if successful;
- /* 注意:关联InitLibrary;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::ReleaseLibrary()
- {
- #ifdef WIN32
- return ( 0 == WSACleanup() );
- #else
- return true;
- #endif
- }
- /************************************************************************/
- /* 函数:WaitForConnection[2/29/2016 IT];
- /* 描述:Wait for a new connection;
- /* 参数:;
- /* [IN] sock:A TCP socket handle. A new socket is return returned;
- /* 返回:return A new socket when a new client connects;
- /* 注意:关联GetSocket, CreateSocket;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- SOCKET CSocketHandle::WaitForConnection(IN SOCKET sock)
- {
- #if 0
- return accept(sock, 0, 0);
- #else
- SOCKET ncs = accept(sock, 0, 0);
- SetKeepLive(ncs);
- return ncs;
- #endif
- }
- /************************************************************************/
- /* 函数:ShutdownConnection[2/29/2016 IT];
- /* 描述:Shutdown a connection;
- /* 参数:;
- /* [IN] sock:Socket to shutdown communication;
- /* 返回:return true if successful;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::ShutdownConnection(IN SOCKET sock)
- {
- shutdown(sock, SD_BOTH);
- return ( 0 == closesocket( sock ));
- }
- static unsigned char chMinClassA_IP [] = { 1, 0, 0, 0 } ;
- static unsigned char chMinClassD_IP [] = { 224, 0, 0, 0 } ;
- static unsigned char chMaxClassD_IP [] = { 239, 255, 255, 255 } ;
- /************************************************************************/
- /* 函数:IsUnicastIP[2/29/2016 IT];
- /* 描述:Check if IP address is unicast (network order);
- /* 参数:;
- /* [IN] ulAddr:IP address (expected valid unicast address);
- /* 返回:return true if successful;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::IsUnicastIP( ULONG ulAddr )
- {
- return (((unsigned char *) & ulAddr) [0] >= chMinClassA_IP [0] &&
- ((unsigned char *) & ulAddr) [0] < chMinClassD_IP [0]) ;
- }
- /************************************************************************/
- /* 函数:IsMulticastIP[2/29/2016 IT];
- /* 描述:Check if IP address is multicast (network order);
- /* 参数:;
- /* [IN] ulAddr:IP address (expected valid multicast address);
- /* 返回:return true if successful;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::IsMulticastIP( ULONG ulAddr )
- {
- return (((unsigned char *) & ulAddr) [0] >= chMinClassD_IP [0] &&
- ((unsigned char *) & ulAddr) [0] <= chMaxClassD_IP [0]) ;
- }
- /************************************************************************/
- /* 函数:FormatIP[2/29/2016 IT];
- /* 描述:Format IP address to string;
- /* 参数:;
- /* [IN] pszIPAddr:Buffer to hold string;
- /* [IN] nSize:Size of buffer in characters;
- /* [IN] ulAddr:IP Address to format;
- /* [IN] bFmtHost:Specify if address (ulAddr) is in host (true) or network format (false);
- /* 返回:return true if successful. Possible error could be INSUFFICIENT_BUFFER;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::FormatIP(LPTSTR pszIPAddr, UINT nSize, ULONG ulAddr, bool bFmtHost)
- {
- if ( pszIPAddr && nSize > 8)
- {
- if ( bFmtHost )
- ulAddr = htonl( ulAddr );
- // Create Address string
- return (SUCCEEDED(StringCchPrintf(pszIPAddr, nSize, TEXT("%u.%u.%u.%u"),
- (UINT)(((PBYTE) &ulAddr)[0]),
- (UINT)(((PBYTE) &ulAddr)[1]),
- (UINT)(((PBYTE) &ulAddr)[2]),
- (UINT)(((PBYTE) &ulAddr)[3]))));
- }
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return false;
- }
- /************************************************************************/
- /* 函数:FormatIP[2/29/2016 IT];
- /* 描述:Format IP address to string;
- /* 参数:;
- /* [IN] pszIPAddr:Buffer to hold string;
- /* [IN] nSize:Size of buffer in characters;
- /* [IN] addrIn:IP Address to format;
- /* 返回:return true if successful. Possible error could be INSUFFICIENT_BUFFER;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::FormatIP(LPTSTR pszIPAddr, UINT nSize, const SockAddrIn& addrIn)
- {
- if ( pszIPAddr && nSize > 8)
- {
- const void* addr;
- char szIPAddr[MAX_PATH] = { 0 };
- if (addrIn.ss_family == AF_INET) {
- addr = &((const sockaddr_in*)&addrIn)->sin_addr;
- } else {
- addr = &((const sockaddr_in6*)&addrIn)->sin6_addr;
- }
- if (inet_ntop(addrIn.ss_family, const_cast<void*>(addr), szIPAddr, MAX_PATH) != NULL)
- {
- #ifdef _UNICODE
- return (0 != MultiByteToWideChar(CP_UTF8, 0, szIPAddr, -1, pszIPAddr, nSize ));
- #else
- ::StringCbCopyA(pszIPAddr, nSize, szIPAddr);
- return true;
- #endif
- }
- }
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return false;
- }
- /************************************************************************/
- /* 函数:GetPortNumber[2/29/2016 IT];
- /* 描述:Get service port number;
- /* 参数:;
- /* [IN] pszServiceName:Network service name (e.g.: "ftp", "telnet") or port number;
- /* 返回:return port number;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- USHORT CSocketHandle::GetPortNumber( LPCTSTR pszServiceName )
- {
- LPSERVENT lpservent;
- USHORT nPort = 0;
- if ( _istdigit( pszServiceName[0] ) ) {
- nPort = (USHORT) _ttoi( pszServiceName );
- }
- else {
- #ifdef _UNICODE
- char pstrService[HOSTNAME_SIZE] = { 0 };
- WideCharToMultiByte(CP_UTF8, 0, pszServiceName, -1, pstrService, sizeof(pstrService), NULL, NULL );
- #else
- LPCTSTR pstrService = pszServiceName;
- #endif
- // Convert network byte order to host byte order
- if ( (lpservent = getservbyname( pstrService, NULL )) != NULL )
- nPort = ntohs( lpservent->s_port );
- }
- return nPort;
- }
- /************************************************************************/
- /* 函数:GetIPAddress[2/29/2016 IT];
- /* 描述:Get IP address of a host;
- /* 参数:;
- /* [IN] pszHostName:host name or IP address;
- /* 返回:return Host IP address in host format;
- /* 注意:关联GetAddressInfo;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- ULONG CSocketHandle::GetIPAddress( LPCTSTR pszHostName )
- {
- LPHOSTENT lphostent;
- ULONG uAddr = INADDR_NONE;
- TCHAR szLocal[HOSTNAME_SIZE] = { 0 };
- // if no name specified, get local
- if ( NULL == pszHostName || !pszHostName[0])
- {
- GetLocalName(szLocal, HOSTNAME_SIZE);
- pszHostName = szLocal;
- }
- #ifdef _UNICODE
- char pstrHost[HOSTNAME_SIZE] = { 0 };
- WideCharToMultiByte(CP_UTF8, 0, pszHostName, -1, pstrHost, sizeof(pstrHost), NULL, NULL );
- #else
- LPCTSTR pstrHost = pszHostName;
- #endif
- // Check for an Internet Protocol dotted address string
- uAddr = inet_addr( pstrHost );
- if ( (INADDR_NONE == uAddr) && (strcmp( pstrHost, "255.255.255.255" )) )
- {
- // It's not an address, then try to resolve it as a hostname
- if ( (lphostent = gethostbyname( pstrHost )) != NULL )
- uAddr = *((ULONG *) lphostent->h_addr_list[0]);
- }
- return ntohl( uAddr );
- }
- /************************************************************************/
- /* 函数:GetLocalName[2/29/2016 IT];
- /* 描述:Get current localname for this machine;
- /* 参数:;
- /* [IN] pszName:Buffer to receive host name;
- /* [IN] nSize:Size of this buffer in character;
- /* 返回:return true if successful;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::GetLocalName(LPTSTR pszName, UINT nSize)
- {
- if (pszName != NULL && nSize > 0)
- {
- char szHost[HOSTNAME_SIZE] = { 0 };
- // get host name, if fail, SetLastError is set
- if (SOCKET_ERROR != gethostname(szHost, sizeof(szHost)))
- {
- struct hostent* hp;
- hp = gethostbyname(szHost);
- if (hp != NULL) {
- ::StringCbCopyA(szHost, HOSTNAME_SIZE, hp->h_name);
- }
- // check if user provide enough buffer
- size_t cbLength = 0;
- ::StringCbLengthA(szHost, HOSTNAME_SIZE, &cbLength);
- if ( cbLength > nSize )
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return false;
- }
- // Unicode conversion
- #ifdef _UNICODE
- return (0 != MultiByteToWideChar(CP_UTF8, 0, szHost, -1, pszName, nSize ));
- #else
- ::StringCbCopyA(pszName, nSize, szHost);
- return true;
- #endif
- }
- else
- SetLastError( WSAGetLastError() );
- }
- else
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
- /************************************************************************/
- /* 函数:GetLocalAddress[2/29/2016 IT];
- /* 描述:Get current (default) IP address for this machine;
- /* 参数:;
- /* [IN] pszAddress:Buffer to receive IP address (IPv4, IPv6 format);
- /* [IN] nSize:Size of this buffer in character;
- /* [IN] nFamily:address family to use (AF_INET, AF_INET6);
- /* 返回:return true if successful;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::GetLocalAddress(LPTSTR pszAddress, UINT nSize, int nFamily /*= AF_INET*/)
- {
- if (pszAddress != NULL && nSize > 0)
- {
- TCHAR szHost[HOSTNAME_SIZE] = { 0 };
- // Get computer local address
- // get host name, if fail, SetLastError is set
- if (GetLocalName(szHost, HOSTNAME_SIZE))
- {
- char szAddress[MAX_PATH] = { 0 };
- #ifdef _UNICODE
- char pstrHost[HOSTNAME_SIZE] = { 0 };
- WideCharToMultiByte(CP_UTF8, 0, szHost, -1, pstrHost, sizeof(pstrHost), NULL, NULL );
- #else
- LPCTSTR pstrHost = szHost;
- #endif
- // get address info
- sockaddr_storage addr_store = { 0 };
- addr_store.ss_family = static_cast<short>(nFamily);
- inet_pton(nFamily, pstrHost, &addr_store);
- const void* addr;
- if (addr_store.ss_family == AF_INET) {
- addr = &((const sockaddr_in*)&addr_store)->sin_addr;
- } else {
- addr = &((const sockaddr_in6*)&addr_store)->sin6_addr;
- }
- if (inet_ntop(addr_store.ss_family, const_cast<void*>(addr), szAddress, MAX_PATH) != NULL)
- {
- // Unicode conversion
- #ifdef _UNICODE
- return (0 != MultiByteToWideChar(CP_UTF8, 0, szAddress, -1, pszAddress, nSize ));
- #else
- ::StringCbCopyA(pszAddress, nSize, szAddress);
- return true;
- #endif
- }
- else
- SetLastError( WSAGetLastError() );
- }
- }
- else
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
- /************************************************************************/
- /* 函数:GetAddressInfo[2/29/2016 IT];
- /* 描述:Get IP address info of a host (Supports: IPv4 and IPv6);
- /* 参数:;
- /* [IN] pszHostName:host name or IP address;
- /* [IN] pszServiceName:pszServiceName Network service name (e.g.: "ftp", "telnet") or port number;
- /* [IN] nFamily:address family to use (AF_INET, AF_INET6);
- /* [IN] sockAddr:Socket address to fill in;
- /* 返回:return true if successful;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- bool CSocketHandle::GetAddressInfo(LPCTSTR pszHostName, LPCTSTR pszServiceName,int nFamily, SockAddrIn& sockAddr, bool bIsClient /* = true */)
- {
- const TCHAR szZERO[] = TEXT("0");
- ADDRINFO aiHints;
- ADDRINFO *aiList = NULL;
- memset(&aiHints, 0, sizeof(aiHints));
- if (bIsClient)
- aiHints.ai_flags = AI_ADDRCONFIG; // 查询配置的地址类型(IPv4或IPv6);
- else
- aiHints.ai_flags = AI_PASSIVE; //socket地址用于监听绑定(通常用于服务端bin);
- aiHints.ai_family = nFamily;
- aiHints.ai_protocol = IPPROTO_IP; // Any protocol;
- TCHAR szLocal[HOSTNAME_SIZE] = { 0 };
- // 客户需要获取计算机名;
- if ( bIsClient && (NULL == pszHostName || !pszHostName[0]))
- {
- GetLocalName(szLocal, HOSTNAME_SIZE);
- pszHostName = szLocal;
- }
- if ( NULL == pszServiceName || !pszServiceName[0])
- {
- pszServiceName = szZERO;
- }
- #ifdef _UNICODE
- char pstrHost[HOSTNAME_SIZE] = { 0 };
- WideCharToMultiByte(CP_UTF8, 0, pszHostName, -1, pstrHost, sizeof(pstrHost), NULL, NULL );
- char pstrService[HOSTNAME_SIZE] = { 0 };
- WideCharToMultiByte(CP_UTF8, 0, pszServiceName, -1, pstrService, sizeof(pstrService), NULL, NULL );
- #else
- LPCTSTR pstrHost = pszHostName;
- LPCTSTR pstrService = pszServiceName;
- #endif
- if ( SOCKET_ERROR != getaddrinfo(pstrHost, pstrService, &aiHints, &aiList) && ( aiList != 0 ))
- {
- #if 1
- ADDRINFO *pCur = NULL;
- SOCKADDR_IN *addr = NULL;
- for ( pCur = aiList; pCur != NULL; pCur = aiList->ai_next )
- {
- addr = (SOCKADDR_IN *)pCur->ai_addr;
- }
- #endif
- ADDRINFO ai = { 0 };
- ai.ai_addr = sockAddr;
- memcpy(ai.ai_addr, aiList->ai_addr, aiList->ai_addrlen);
- freeaddrinfo( aiList );
- return true;
- }
- SetLastError( WSAGetLastError() );
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Globals
- ///////////////////////////////////////////////////////////////////////////////
- #if !defined(PLATFORM_HAS_INETFUNC)
- ///////////////////////////////////////////////////////////////////////////////
- // inet_ntop
- #if 0
- const char *inet_ntop(int af, const void *src, char *dst, size_t cnt)
- {
- if ( dst != NULL)
- {
- dst[0] = 0;
- if (af == AF_INET)
- {
- sockaddr_in in;
- memset(&in, 0, sizeof(in));
- in.sin_family = AF_INET;
- memcpy(&in.sin_addr, src, sizeof(in_addr));
- getnameinfo((sockaddr *)&in, sizeof(sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
- return dst;
- }
- else if (af == AF_INET6)
- {
- sockaddr_in6 in;
- memset(&in, 0, sizeof(in));
- in.sin6_family = AF_INET6;
- memcpy(&in.sin6_addr, src, sizeof(in6_addr));
- getnameinfo((sockaddr *)&in, sizeof(sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
- return dst;
- }
- }
- WSASetLastError(WSA_INVALID_PARAMETER);
- return dst;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // inet_pton
- int inet_pton(int af, const char *src, void *dst)
- {
- int result = SOCKET_ERROR;
- addrinfo aiHints, *aiList = NULL;
- memset(&aiHints, 0, sizeof(aiHints));
- aiHints.ai_family = af;
- if ( SOCKET_ERROR != getaddrinfo(src, NULL, &aiHints, &aiList) && (aiList != NULL))
- {
- memcpy(dst, aiList->ai_addr, aiList->ai_addrlen);
- freeaddrinfo(aiList);
- result = 0;
- }
- return result;
- }
- #else
- //////////////////////////////////////////////////////////////////////////
- static const char * inet_ntop_v4 (const void *src, char *dst, size_t size)
- {
- const char digits[] = "0123456789";
- int i;
- struct in_addr *addr = (struct in_addr *)src;
- u_long a = ntohl(addr->s_addr);
- const char *orig_dst = dst;
- if (size < INET_ADDRSTRLEN) {
- errno = ENOSPC;
- return NULL;
- }
- for (i = 0; i < 4; ++i) {
- int n = (a >> (24 - i * 8)) & 0xFF;
- int non_zerop = 0;
- if (non_zerop || n / 100 > 0) {
- *dst++ = digits[n / 100];
- n %= 100;
- non_zerop = 1;
- }
- if (non_zerop || n / 10 > 0) {
- *dst++ = digits[n / 10];
- n %= 10;
- non_zerop = 1;
- }
- *dst++ = digits[n];
- if (i != 3)
- *dst++ = '.';
- }
- *dst++ = '\0';
- return orig_dst;
- }
- #ifdef HAVE_IPV6
- static const char * inet_ntop_v6 (const void *src, char *dst, size_t size)
- {
- const char xdigits[] = "0123456789abcdef";
- int i;
- const struct in6_addr *addr = (struct in6_addr *)src;
- const u_char *ptr = addr->s6_addr;
- const char *orig_dst = dst;
- int compressed = 0;
- if (size < INET6_ADDRSTRLEN) {
- errno = ENOSPC;
- return NULL;
- }
- for (i = 0; i < 8; ++i) {
- int non_zerop = 0;
- if (compressed == 0 &&
- ptr[0] == 0 && ptr[1] == 0 &&
- i <= 5 &&
- ptr[2] == 0 && ptr[3] == 0 &&
- ptr[4] == 0 && ptr[5] == 0) {
- compressed = 1;
- if (i == 0)
- *dst++ = ':';
- *dst++ = ':';
- for (ptr += 6, i += 3;
- i < 8 && ptr[0] == 0 && ptr[1] == 0;
- ++i, ptr += 2);
- if (i >= 8)
- break;
- }
- if (non_zerop || (ptr[0] >> 4)) {
- *dst++ = xdigits[ptr[0] >> 4];
- non_zerop = 1;
- }
- if (non_zerop || (ptr[0] & 0x0F)) {
- *dst++ = xdigits[ptr[0] & 0x0F];
- non_zerop = 1;
- }
- if (non_zerop || (ptr[1] >> 4)) {
- *dst++ = xdigits[ptr[1] >> 4];
- non_zerop = 1;
- }
- *dst++ = xdigits[ptr[1] & 0x0F];
- if (i != 7)
- *dst++ = ':';
- ptr += 2;
- }
- *dst++ = '\0';
- return orig_dst;
- }
- #endif /* HAVE_IPV6 */
- const char * inet_ntop(int af, const void *src, char *dst, size_t size)
- {
- switch (af) {
- case AF_INET :
- return inet_ntop_v4 (src, dst, size);
- #ifdef HAVE_IPV6
- case AF_INET6 :
- return inet_ntop_v6 (src, dst, size);
- #endif
- default :
- //errno = EAFNOSUPPORT;
- return NULL;
- }
- }
- int inet_pton(int af, const char *csrc, void *dst)
- {
- char * src;
- if (csrc == NULL || (src = strdup(csrc)) == NULL) {
- _set_errno( ENOMEM );
- return 0;
- }
- switch (af) {
- case AF_INET:
- {
- struct sockaddr_in si4;
- INT r;
- INT s = sizeof(si4);
- si4.sin_family = AF_INET;
- r = WSAStringToAddress(src, AF_INET, NULL, (LPSOCKADDR) &si4, &s);
- free(src);
- src = NULL;
- if (r == 0) {
- memcpy(dst, &si4.sin_addr, sizeof(si4.sin_addr));
- return 1;
- }
- }
- break;
- case AF_INET6:
- {
- struct sockaddr_in6 si6;
- INT r;
- INT s = sizeof(si6);
- si6.sin6_family = AF_INET6;
- r = WSAStringToAddress(src, AF_INET6, NULL, (LPSOCKADDR) &si6, &s);
- free(src);
- src = NULL;
- if (r == 0) {
- memcpy(dst, &si6.sin6_addr, sizeof(si6.sin6_addr));
- return 1;
- }
- }
- break;
- default:
- _set_errno( ENOSYS/*EAFNOSUPPORT*/ );
- return -1;
- }
- /* the call failed */
- {
- int le = WSAGetLastError();
- if (le == WSAEINVAL)
- return 0;
- _set_errno(le);
- return -1;
- }
- }
- #endif
- #endif
|