Linux下c实现域名转IP的方法封装

来源:互联网 发布:算法导论英文版 百度云 编辑:程序博客网 时间:2024/06/05 17:20

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(100);// 0.1ms延时    }    pthread_cancel(gs.thread_id);    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 -lpthreadclean:    @rm -rf urlIpTest
阅读全文
0 0