/*
Author :decwang@2014.09.01
Mail :deworks@sina.com
*/
#define PRINTLOG printf
//返回0表示成功,其他为失败. int getIpAddressByGetAddrInfo(const char* address,char* realIP,int maxLen) { if (NULL == address || NULL == realIP) { PRINTLOG("param address wrong "); return -1; } struct addrinfo *answer = NULL, hint, *curr = NULL; bzero(&hint, sizeof(hint)); hint.ai_family = AF_INET; hint.ai_socktype = SOCK_STREAM; int ret = getaddrinfo(address, NULL, &hint, &answer); if (ret != 0) { PRINTLOG("error on getaddrinfo: ret: %s ",gai_strerror(ret)); return -2; } for (curr = answer; curr != NULL; curr = curr->ai_next) { inet_ntop(AF_INET,&(((struct sockaddr_in *)(curr->ai_addr))->sin_addr),realIP, maxLen); PRINTLOG("realIP is %s ", realIP); break; } freeaddrinfo(answer); return 0; }
//返回1表示网络可达,返回其他为失败 int isReachable(const char* address,int port,int timeout) { if (NULL == address) { PRINTLOG("param address wrong "); return -1; } if (timeout <= 0) { PRINTLOG("param timeout wrong "); return -1; } struct sockaddr_in server_addr; char realIP[128]; memset(realIP,0,sizeof(realIP)); int nRet = getIpAddressByGetAddrInfo(address, realIP, 128-1); if (nRet != 0) { PRINTLOG("get real ip address failed "); return -1; } if (port >= 65535 || port <= 0) { PRINTLOG("port invalid "); return -1; } int sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd < 0) { PRINTLOG("create socket failed "); return -2; } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr.s_addr = inet_addr(realIP); int error=-1, len; len = sizeof(int); struct timeval tm; fd_set set; fcntl(sockfd, F_SETFL, O_NONBLOCK); if( connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) ==-1) { tm.tv_sec = timeout; tm.tv_usec = 0; FD_ZERO(&set); FD_SET(sockfd, &set); if( select(sockfd+1, NULL, &set, NULL, &tm) > 0) { getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len); if(error == 0) nRet = 1; else nRet = 0; } else nRet = 0; } else nRet = 1; close( sockfd ); return nRet; }
这段代码是为了修正之前的iOS上的双网络连接探测用的,之前的SCNetWork对网络的状态判断存在,故干脆采用直接连接的方式进行判断