使用getaddrinfo获取DNS信息

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netdb.h>

#define GET_CMD "GET %s HTTP/1.1\r\nConnection: Keep-Alive\r\n\r\n"

#define array_size(array) \
    (sizeof(array)/sizeof(array[0]))

#define for_each(head, ptr) \
    for(ptr = head; ptr != NULL; ptr = ptr->ai_next)

struct web_database
{
    const char* hostname;
    const char* service;
    FILE* file;
}database[] = { 
    {"www.baidu.com", "80", NULL}, 
    {"www.renren.com","80", NULL}, 
    {"www.nwpu.edu.cn", "80", NULL}, 
    {"www.bjtu.edu.cn", "80", NULL}, 
    {"www.openlan.net", "80", NULL},
    {"www.google.com", "80", NULL},
    {"web.qq.com", "80", NULL},
    {"www.cnblog.com", "80", NULL}
};


struct addrinfo* host_svr(const char* hostname,	 const char* service,
int family,
int sock_type)
{
    int n;
    struct addrinfo hints;
    struct addrinfo* res;
    memset(&hints, 0, sizeof(hints));

    hints.ai_flags = AI_CANONNAME;
    hints.ai_family = family;
    hints.ai_socktype = sock_type;

    if((n = getaddrinfo(hostname, service, &hints, &res)) != 0)
    {
    printf("getaddrinfo error: %s\n", gai_strerror(n));
    return NULL;
    }

    return res;
}

int tcp_connect(const char* hostname, const char* service)
{
    int sockfd;
    int n;
    struct addrinfo hints;
    struct addrinfo* res;
    struct addrinfo* ressave;

    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_family = AF_INET;

    if((n = getaddrinfo(hostname, service, &hints, &res)) != 0)
    {
        printf("getaddrinfo failed: %s, %s, %s\n", hostname, service, gai_strerror(n));
        return -1;
    }
    ressave = res;

    do
    {
        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if(sockfd < 0)
            continue;
        if(connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
        break;
        close(sockfd);
    }while((res = res->ai_next) != NULL);
    if(res == NULL)
    printf("getaddrinfo error\n");

    freeaddrinfo(ressave);
    return sockfd;
}

int main()
{
    int sockfd;
    int n;
    struct addrinfo* res_head;
    struct addrinfo* ptr;
    int ret;
    char buffer[1024] = {0};
    for(n = 0; n != array_size(database); n++)
    {
        res_head = host_svr(database[n].hostname, database[n].service, AF_INET, SOCK_STREAM);
        for_each(res_head, ptr)
            printf("%s ip: %s\ncanonname: %s\n", database[n].hostname, inet_ntoa(((struct sockaddr_in*)(ptr->ai_addr))->sin_addr), ptr->ai_canonname);
        sockfd = tcp_connect(database[n].hostname, database[n].service);

        snprintf(buffer, sizeof(buffer), GET_CMD, "/");
        printf("cmd: %s\n", buffer);
        ret = write(sockfd, buffer, strlen(buffer));
        database[n].file = fopen(database[n].hostname, "w+");
        if(database[n].file < 0)
        printf("%s file create failed\n", database[n].hostname);
        ret = read(sockfd, buffer, 1024);
        fprintf(database[n].file, "%s", buffer);
        close(sockfd);

    }
    return 0;
}


转载于:https://my.oschina.net/u/256193/blog/49680

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值