struct IP_ADDR_INFO
{
int ip_ver;//4 表示ipv4 6表示ipv6
int ai_family;
int ai_socktype;
int ai_protocol;
char ipstr[128];
};
inline int GetIpAddrTableByHostName(const char* szHostName,IP_ADDR_INFO* ipAddrArray,int ipAddrArrLen,int* ipAddrCount)
{
struct addrinfo *answer, hint, *curr;
bzero(&hint, sizeof(hint));
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
//hint.ai_flags = AI_DEFAULT;
int ret = getaddrinfo(szHostName, NULL, &hint, &answer);
if (ret != 0) {
NOTIFY_LOG("GetIpAddrTableByHostName|get addrinfo error:%d %s host:%s",ret,gai_strerror(ret),szHostName ) ;
return -1;
}
char ipstr1[32];
char ipstr2[128];
struct sockaddr_in *sockaddr_ipv4;
struct sockaddr_in6 *sockaddr_ipv6;
int ipcount = 0;
for (curr = answer; curr != NULL; curr = curr->ai_next)
{
switch(curr->ai_family )
{
case AF_UNSPEC:
break;
case AF_INET6:
{
sockaddr_ipv6 = reinterpret_cast<struct sockaddr_in6 *>( curr->ai_addr);
inet_ntop(AF_INET6, &sockaddr_ipv6->sin6_addr, ipstr2,sizeof(ipstr2));
IP_ADDR_INFO ipaddrinfo;
ipaddrinfo.ai_family= curr->ai_family;
ipaddrinfo.ai_socktype =curr->ai_socktype;
ipaddrinfo.ai_protocol = curr->ai_protocol;
ipaddrinfo.ip_ver = 6;
strcpy(ipaddrinfo.ipstr,ipstr2);
DEBUG_LOG("GetIpAddrTableByHostName()|%s ->ip_ver:%d ip_str:%s",szHostName,ipaddrinfo.ip_ver,ipaddrinfo.ipstr);
if (ipcount < ipAddrArrLen )
{
ipAddrArray[ipcount] = ipaddrinfo;
ipcount++;
}
}
break;
case AF_INET:
{
sockaddr_ipv4 = reinterpret_cast<struct sockaddr_in *>( curr->ai_addr);
inet_ntop(AF_INET, &sockaddr_ipv4->sin_addr, ipstr1,sizeof(ipstr1));
IP_ADDR_INFO ipaddrinfo;
ipaddrinfo.ai_family= curr->ai_family;
ipaddrinfo.ai_socktype =curr->ai_socktype;
ipaddrinfo.ai_protocol = curr->ai_protocol;
ipaddrinfo.ip_ver = 4;
strcpy(ipaddrinfo.ipstr,ipstr1);
DEBUG_LOG("GetIpAddrTableByHostName()|%s ->ip_ver:%d ip_str:%s",szHostName,ipaddrinfo.ip_ver,ipaddrinfo.ipstr);
if (ipcount < ipAddrArrLen )
{
ipAddrArray[ipcount] = ipaddrinfo;
ipcount++;
}
}
break;
}
}
freeaddrinfo(answer);
answer=NULL;
*ipAddrCount=ipcount;
return 0;
}
//Refence:https://www.ibm.com/developerworks/cn/linux/l-cn-ipv4v6-sockapp/
inline int CreateConnectSocket(IP_ADDR_INFO* ipaddrinfo,uint32_t uPort)
{
int nConnectFd=-1;
struct sockaddr* connectAddr=NULL; ;
struct sockaddr_in svraddrV4 ;
struct sockaddr_in6 svraddrV6 ;
socklen_t socklen ;
if (ipaddrinfo->ip_ver == 4)
{
bzero(&svraddrV4,sizeof(svraddrV4));
svraddrV4.sin_family = AF_INET;
svraddrV4.sin_port = htons( uPort ) ;
svraddrV4.sin_addr.s_addr = inet_addr( ipaddrinfo->ipstr ) ;
socklen = sizeof( svraddrV4 ) ;
connectAddr = (sockaddr *)&svraddrV4 ;
}
else if (ipaddrinfo->ip_ver == 6)
{
bzero(&svraddrV6,sizeof(svraddrV6));
svraddrV6.sin6_family = AF_INET6;
svraddrV6.sin6_port = htons(uPort) ;
inet_pton( AF_INET6,ipaddrinfo->ipstr ,&svraddrV6.sin6_addr ) ;
socklen = sizeof(svraddrV6) ;
connectAddr = (sockaddr *)&svraddrV6 ;
}
else
{
NOTIFY_LOG("CreateConnectSocket()|invalid ipver;ip_ver:%d ip_str:%s port:%u",ipaddrinfo->ip_ver,ipaddrinfo->ipstr,uPort);
return -1;
}
nConnectFd= socket( ipaddrinfo->ai_family, ipaddrinfo->ai_socktype, ipaddrinfo->ai_protocol ) ;
if (nConnectFd<0)
{
NOTIFY_LOG("CreateConnectSocket()|socket() error;ip_ver:%d ip_str:%s port:%u",ipaddrinfo->ip_ver,ipaddrinfo->ipstr,uPort);
return -1;
}
SetNoblock( nConnectFd ) ;
int set = 1;
setsockopt( nConnectFd, SOL_SOCKET, MSG_NOSIGNAL, (void *)&set, sizeof(int));
int nErr;
int rc = ::connect( nConnectFd, connectAddr, socklen );
if (rc < 0 )
{
nErr = errno ;
if (! isSocketInPending(nErr))
{
closesocket(nConnectFd);
NOTIFY_LOG("CreateConnectSocket()|connect() error;ip_ver:%d ip_str:%s port:%u",ipaddrinfo->ip_ver,ipaddrinfo->ipstr,uPort);
return -1;
}
}
NOTIFY_LOG("CreateConnectSocket()|connect() try...;ip_ver:%d ip_str:%s port:%u",ipaddrinfo->ip_ver,ipaddrinfo->ipstr,uPort);
return nConnectFd ;
}
通过域名连接服务器
最新推荐文章于 2024-01-29 15:42:11 发布