名字与地址转换

gethostbyname/gethostbyaddr

均用于IPv4中, 第一个通过域名查ip地址, 第二个通过ip地址反向查询域名.
不过需要注意的反向查询需要本地有反射解析服务, 或者说本地的etc/hosts文件中有相应的记录

#include <netdb.h>
struct hostent *gethostbyname(const char *hostname);
struct hostent *gethostbyaddr(const char *addr,socklen_t len,int family);
 
 
struct hostent{
    char *h_name;   //域名
 
    char **h_aliases; //别名
 
    int h_addrtype;  //AF_INET
 
    int h_length; // 4
 
    char **h_addr_list; //域名对应的IPv4地址链
 
}

gethostbyname的参数是域名的字符串
gethostbyaddr的第一个参数是IPv4地址的二进制字符串

#include "unp.h"
#include <netdb.h>
 
int main(int argc, char *argv[])
{
    char *ptr,**pptr;
    char str[INET_ADDRSTRLEN];
    struct hostent *hptr;
 
    while(--argc > 0){
        ptr = *++argv;
        if((hptr=gethostbyname(ptr)) == NULL){
            printf("gethostbyname error for host: %s: %s",
                    ptr,hstrerror(h_errno));
            continue;
        }
        printf("official hostname: %s\n",hptr->h_name);
 
        for(pptr=hptr->h_aliases;*pptr != NULL;pptr++)
            printf("\talias: %s\n",*pptr);
        switch(hptr->h_addrtype){
            case AF_INET:
                pptr=hptr->h_addr_list;
                for(;*pptr != NULL;pptr++)
                    printf("\taddress: %s\n",inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str)));
                break;
            default:
                printf("unknown address type\n");
                break;
        }
    }
    return 0;
}
#include "unp.h"
#include <netdb.h>
 
int main(int argc, char *argv[])
{
    char *ptr,**pptr;
    char str[INET_ADDRSTRLEN];
    struct hostent *hptr;
    struct in_addr *addr;
    struct sockaddr_in saddr;
 
    while(--argc > 0){
        ptr = *++argv;
        if(!inet_aton(ptr,&saddr.sin_addr))
            err_quit("inet_aton error");
 
        if((hptr=gethostbyaddr((void *)&saddr.sin_addr,sizeof(struct in_addr),AF_INET)) == NULL)
            err_quit("gethostbyaddr error:%s %s ",ptr, hstrerror(h_errno) );
 
        printf("official hostname: %s\n",hptr->h_name);
 
        for(pptr=hptr->h_aliases;*pptr!=NULL;pptr++)
            printf("\talias: %s\n",*pptr);
 
        switch(hptr->h_addrtype){
            case AF_INET:
                pptr=hptr->h_addr_list;
                for(;*pptr != NULL;pptr++)
                    printf("\taddress:%s\n",
                            inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str)));
                break;
            default:
                puts("unknown address type\n");
                break;
        }
    }
    return 0;
}

getservbyname/getservbyport

大致就是输入http输出80; 输入21输出ftp

#include <netdb.h>
struct servent *getservbyname(const char *servname, const char *protoname);
struct servent *getservbyport(int port, const char *protoname);
 
 
struct servent{
    char *s_name; /* http,ftp... */
    char **s_aliases; /* 别名 */
    int s_port; /* 端口号 */
    char *s_proto; /* tcp 或 udp */
}

getservbyport中的port参数需要网络字节序

#include "unp.h"
#include <netdb.h>
 
int main(int argc, char *argv[])
{
    struct servent *ent;
 
    if(argc < 2)
        err_quit("usage: ./port2name [port]");
    if((ent=getservbyport(htons(atoi(argv[1])),"tcp")) == NULL)
        err_quit("getservent error");
 
    printf("official name: %s\n",ent->s_name);
    printf("port %d\n",ntohs(ent->s_port));
    return 0;
}
#include "unp.h"
#include <netdb.h>
 
int main(int argc, char *argv[])
{
    struct servent *ent;
 
    if(argc < 2)
        err_quit("usage: ./name2port [service_name]");
    if((ent=getservbyname(argv[1],"tcp")) == NULL)
        err_quit("getservent error");
 
    printf("official name: %s\n",ent->s_name);
    printf("port %d\n",ntohs(ent->s_port));
    return 0;
}
posted @ 2016-12-04 21:16  cfans1993  阅读(191)  评论(0编辑  收藏  举报