通过域名连接服务器

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 ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值