arm开发板下运行时请确认你的开发板已联网
cat /etc/resolv.conf是否为空
urlIpTest_main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h> //
#include <netdb.h> // gethostbyname, gethostbyname2, gethostbyname_r, gethostbyname_r2
#include <setjmp.h>
#include <errno.h>
#include <fcntl.h> // 非阻塞关键字
#include <stdbool.h> // 使用bool变量
#include <pthread.h> // 使用多线程
void delayus(unsigned int us)
{
struct timeval tim;
tim.tv_sec = us/1000000;
tim.tv_usec = us%1000000;
select(0, NULL, NULL, NULL, &tim);
}
////////////////////////////////// 域名转IP //////////////////////////////////
// 封装个和线程交互用的结构体
typedef struct{
pthread_t thread_id;
char ip[256];
bool result;
bool actionEnd;
}GetHostName_Struct;
// 调用 gethostbyname_r 函数需在单独的线程中调用, 阻塞时还可以外部超时退出
void *getHost_fun(void *arge)
{
int ret;
int i;
char buf[1024];
struct hostent host_body, *host;
struct in_addr **addr_list;
GetHostName_Struct *gs = (GetHostName_Struct *)arge;
/* 此类方法不可重入! 即使关闭线程
if((host = gethostbyname(gs->ip)) == NULL)
//if((host = gethostbyname2(gs->ip, AF_INET)) == NULL)
{
gs->actionEnd = true;
return NULL;
}*/
if(gethostbyname_r(gs->ip, &host_body, buf, sizeof(buf), &host, &ret))
{
gs->actionEnd = true;
return NULL;
}
if(host == NULL)
{
gs->actionEnd = true;
return NULL;
}
addr_list = (struct in_addr **)host->h_addr_list;
// 查看获得的ip列表
/*printf("ip name : %s\r\nip list : ", host->h_name);
for(i = 0; addr_list[i] != NULL; i++)
printf("%s, ", inet_ntoa(*addr_list[i]));
printf("\r\n");*/
// 默认返回列表第一条ip
if(addr_list[0] == NULL)
{
gs->actionEnd = true;
return NULL;
}
memset(gs->ip, 0, sizeof(gs->ip));
strcpy(gs->ip, (char *)inet_ntoa(*addr_list[0]));
gs->result = true;
gs->actionEnd = true;
return NULL;
}
// 封装方法, 成功返回调用耗时, 错误返回负数的耗时 (ms)
int getIpFromHostName(char *hostName, char *backIp)
{
int i, timeOut = 1;
GetHostName_Struct gs;
if(hostName == NULL)
return -1;
else if(strlen(hostName) < 1)
return -1;
//----- 开线程从域名获取IP -----
memset(&gs, 0, sizeof(GetHostName_Struct));
strcpy(gs.ip, hostName);
gs.result = false;
gs.actionEnd = false;
if (pthread_create(&gs.thread_id, NULL, getHost_fun, &gs) < 0)
return -1;
i = 0;
while(!gs.actionEnd)
{
if(++i > 10)
{
i = 0;
if(++timeOut > 1000) // 1s 超时
break;
}
delayus(1000);// 1ms延时
}
//pthread_cancel(gs.thread_id);//必须让系统跑完,否则内存不能释放
pthread_join(gs.thread_id, NULL);
if(!gs.result)
return -timeOut;
//----- 开线程从域名获取IP -----
memset(backIp, 0, strlen(backIp));
strcpy(backIp, gs.ip);
return timeOut;
}
////////////////////////////////// 域名转IP //////////////////////////////////
int main(int argc, char *argv[])
{
char ip[128] = {0};
int ret;
//
if(argc < 2)
{
printf("input such as : ./urlIpTest www.baidu.com\r\n");
return 0;
}
//
if((ret = getIpFromHostName(argv[1], ip)) > 0)
printf("host(%s) to ip(%s) , ret/%d\r\n", argv[1], ip, ret);
else
printf("test failed , ret/%d\r\n", ret);
//
return 0;
}
// 在tcp连接时的使用
/*
...
{
...
struct sockaddr_in sock_addr;
memset(&sock_addr,0,sizeof(sock_addr));
sock_addr.sin_family=AF_INET;
//获取IP不成功时可尝试调用域名转换
if((sock_addr.sin_addr.s_addr = inet_addr(ip)) == INADDR_NONE)
{
//printf("url is : %s\r\n", ip);
//
memset(buf, 0, sizeof(buf));
ret = getIpFromHostName(ip, buf);
if(ret < 0)
return ret;
else if(strlen(buf) < 7)
return -ret;
//
if((sock_addr.sin_addr.s_addr = inet_addr(buf)) == INADDR_NONE)
return -ret;
printf("Host(%s) to Ip(%s)\r\n", ip, buf);
}
...
}
*/
Makefile:
#CC=arm-linux-gnueabihf-
CC=
target:
$(CC)gcc -O3 -o urlIpTest urlIpTest_main.c -lpthread
clean:
@rm -rf urlIpTest