check if the service is available

Now we meet a case that the IP address list returned by DNS server contains IPv6 address and IPv4 address. The IPv6 address is at the beginning of the list. In fact, it is invalid to connect. In this case, we need to find a valid IP address from the list. But the time spent in finding should be not too long.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <sys/ioctl.h>

#define INIT_ADDR(dest4,dest6,dest,_ip,_port,addrlen) \
memset(&dest4, 0, sizeof(dest4));\
memset(&dest6, 0, sizeof(dest6));\
if(af_family == AF_INET){\
dest4.sin_family = AF_INET;\
dest4.sin_addr.s_addr = inet_addr(_ip);\
dest4.sin_port = htons(_port);\
dest = (struct sockaddr *)&dest4;\
addrlen = sizeof(dest4);\
}\
else if(af_family == AF_INET6){\
dest6.sin6_family = AF_INET6;\
inet_pton(AF_INET6, _ip, &dest6.sin6_addr);\
dest6.sin6_port = htons(_port);\
dest = (struct sockaddr *)&dest6;\
addrlen = sizeof(dest6);\
}

char ipaddr[128];

int check_service(int af_family, char *ipaddr, int portno)
{
int local_sockfd=0;
struct sockaddr_in  dest4;
struct sockaddr_in6 dest6;
struct sockaddr    *dest;
int addrlen;
unsigned long fc=1;

int retval, errlen, error;
struct timeval timeout;
fd_set fds;

INIT_ADDR(dest4,dest6,dest,ipaddr,portno,addrlen);

if ((local_sockfd=socket(af_family, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "Socket Error:%s\a\n", strerror(errno));
return 0;
}

if (ioctl(local_sockfd, FIONBIO, &fc) == -1) {
printf("ioctl error.\n");
return 0;
}


if (connect(local_sockfd, dest, addrlen) == -1) {
if (errno != EINPROGRESS) {
printf("Network is unreachable.\n");
return 0;
}

errlen = sizeof(int);
FD_ZERO(&fds);
FD_SET(local_sockfd, &fds);
timeout.tv_sec = 2;
timeout.tv_usec = 0;

if ((retval = select(local_sockfd + 1, NULL, &fds, NULL, &timeout)) > 0) {
getsockopt(local_sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&errlen);
if (error == 0) {
printf("OK\n");
}
else {
printf("error\n");
return 0;
}
}
else {
printf("Connect Timeout\n");
return 0;
}


}


close(local_sockfd);
return 1;
}


int main(int argc, const char *argv[])
{
char host_buf[128]={"www.baidu.com"};
struct addrinfo hints;
struct addrinfo *res = NULL;


memset(&hints, 0, sizeof(hints));


hints.ai_socktype = SOCK_STREAM;
getaddrinfo(host_buf, NULL, &hints, &res);


while (res) {
if (res->ai_family == AF_INET) {
inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, ipaddr, ACS_IP_LEN);
if (check_service(AF_INET, ipaddr, 80)) {
break;
}
}
else if (res->ai_family == AF_INET6) {
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, ipaddr, ACS_IP_LEN);
if (check_service(AF_INET6, ipaddr, 80)) {
break;
}
}
res = res->ai_next;
}


return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值