UNP函数笔记八: 名字与地址转换

来源:互联网 发布:企业网站怎样优化 编辑:程序博客网 时间:2024/04/27 06:07

第十一章  名字与地址转换:

#include <netdb.h>struct hostnet * gethostbyname(const char * hostname);    error return NULL and set h_errno    struct hostnet {        char  * h_name;       /* official (canonical) name of host */        char ** h_aliases;    /* alias name */        int     h_addrtype;   /* host addr type: AF_INET */        int     h_length;     /* length of address: 4 */        char ** h_addr_list;  /* IPv4 addrs */    };    h_errno:        HOST_NOT_FOUND, TRY_AGAIN, NO_RECOVERY, NO_DATA(NO_ADDRESS)#include <netdb.h>struct hostnet * gethostbyaddr(const char * addr, socklen_t len, int family);    error return NULL and set h_errno    addr:        real type is struct in_addr    family:        AF_INET    len:        4, sizeof(struct in_addr)#include <netdb.h>struct servent * getservbyname(const char * servname, const char * protoname);    error return NULL    struct servent {        char  * s_name;    /* official service name */        char ** s_aliases; /* alias list */        int     s_port;    /* network byte order */        char  * s_proto;   /* protocol to use */    };    protoname:        "tcp", "udp", NULL#include <netdb.h>struct servent * getservbyport(int port, const_char * protoname);    error return NULL    port:        network byte order    protoname:        "tcp", "udp", NULL#include <netdb.h>int getaddrinfo(const char * hostname, const char * service,                 const struct addrinfo * hints, struct addrinfo ** result);    success return 0, failed return error(EAI_xxx)    error:        EAI_AGAIN,  EAI_BADFLAGS, EAI_FAIL,    EAI_FAMILY,   EAI_MEMORY,         EAI_NONAME, EAI_OVERFLOW, EAI_SERVICE, EAI_SOCKTYPE, EAI_SYSTEM    struct addrinfo {        int         ai_flags;        int         ai_family;        int         ai_socktype;        int         ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */        socklen_t   ai_addrlen;  /* length of ai_addr */        char      * ai_canonname;        struct sockaddr * ai_addr;        struct addrinfo * ai_next;    };    hints only can set: ai_flags, ai_family, ai_socktype, ai_protocol    ai_flags:        AI_PASSIVE,  AI_CANONNAME, AI_NUMERICHOST, AI_NUMERICSERV,         AI_V4MAPPED, AI_ALL,       AI_ADDRCONFIG#include <netdb.h>const char * gai_strerror(int error);#include <netdb.h>void freeaddrinfo(struct addrinfo * ai);some hostname:    0::0, 0.0.0.0; 0::1, 127.0.0.1#include <netdb.h>int getnameinfo(const struct sockaddr * sockaddr, socklen_t addrlen,                 char * host, socklen_t hostlen,                 char * serv, socklen_t servlen, int flags);    success return 0, failed return error(EAI_xxx)    flags:        NI_DGRAM,       NI_NAMEREQD,     NI_NOFQDN,         NI_NUMERICHOST, NI_NUMERICSCOPE, NI_NUMERICSERV#include <netdb.h>struct hostent * gethostbyname_r(const char * hostname,                                  struct hostnet * result,                                  char * buf, int buflen, int * h_errnop);    error return NULL    buflen should >= 8192struct hostent * gethostbyaddr_r(const char * addr, int len, int type,                                  struct hostnet * result,                                  char * buf, int buflen, int * h_errnop);    error return NULL    buflen should >= 8192other functions:    getXXXent, setXXXent, endXXXent        XXX:host, net, proto, serv    getnetbyaddr, getnetbyname,     getprotobyname, getprotobynumber

示例:

#include <netdb.h>#include "err_exit.h"int main(int argc, char ** argv){    char           *  ptr;    char           ** 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\n",                   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) {                    if (inet_ntop(hptr->h_addrtype, *pptr,                                   str, sizeof(str)) == NULL) {                        err_exit("inet_ntop error");                    }                    printf("\taddress: %s\n", str);                }                break;            }            default:            {                err_exit("unknown address type");                break;            }        }    }    exit(0);}

#include <netdb.h>#include "err_exit.h"#include "sock_ntop.h"#define MAXLINE 4096int main(int argc, char ** argv){    int                   sockfd;    int                   n;    char                * paddr;    char                  recvline[MAXLINE + 1];    struct sockaddr_in    servaddr;    struct in_addr     ** pptr;    struct in_addr      * inetaddrp[2];    struct in_addr        inetaddr;    struct hostent      * hp;    struct servent      * sp;    if (argc != 3) {        printf("usage: daytimetcpcli1 <hostname> <service>\n");        exit(1);    }    if ((hp = gethostbyname(argv[1])) == NULL) {        if (inet_aton(argv[1], &inetaddr) <= 0) {            printf("hostname error for %s: %s\n", argv[1], hstrerror(h_errno));            exit(1);        }        else {            inetaddrp[0] = &inetaddr;            inetaddrp[1] = NULL;            pptr = inetaddrp;        }    }    else {        pptr = (struct in_addr **)hp->h_addr_list;    }    if ((sp = getservbyname(argv[2], "tcp")) == NULL) {        printf("gethostbyname error for host: %s: %s\n",               argv[2], hstrerror(h_errno));        exit(1);    }    for (; *pptr != NULL; ++pptr) {        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {            err_exit("socket error");        }        bzero(&servaddr, sizeof(servaddr));        servaddr.sin_family = AF_INET;        servaddr.sin_port = sp->s_port;        memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));        if ((paddr = sock_ntop((struct sockaddr *)&servaddr,                                sizeof(servaddr))) == NULL) {            err_exit("sock_ntop error");        }        printf("trying %s\n", paddr);        if (connect(sockfd, (struct sockaddr *)&servaddr,                     sizeof(servaddr)) == 0) {            break;  /* success */        }        printf("connect error: %s\n", strerror(errno));        if (close(sockfd) == -1) {            err_exit("close error");        }    }    if (*pptr == NULL) {        printf("unable to connect");        exit(1);    }    while ((n = read(sockfd, recvline, MAXLINE)) > 0) {        recvline[n] = '\0';  /* null terminate */        if (fputs(recvline, stdout) == EOF) {            err_exit("fputs error");        }    }    if (n < 0) {        err_exit("read error");    }    exit(0);}

#include <stdio.h>#include <netdb.h>#include <strings.h>struct addrinfo * host_serv(const char * host, const char * serv, int family, int socktype){    int               n;    struct addrinfo   hints;    struct addrinfo * res;    bzero(&hints, sizeof(struct addrinfo));    hints.ai_flags = AI_CANONNAME;  /* always return canonical name */    hints.ai_family = family;       /* AF_UNSPEC, AF_INET, AF_INET6, etc. */    hints.ai_socktype = socktype;   /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0) {        printf("host_serv error for %s, %s: %s\n",                (host == NULL) ? "(no hostname)" : host,                (serv == NULL) ? "(no servname)" : serv,                gai_strerror(n));        exit(1);    }    return(res);  /* return pointer to first on linked list */}

#include <netdb.h>#include <strings.h>#include "err_exit.h"#define LISTENQ 1024int tcp_listen(const char * host, const char * serv, socklen_t * addrlenp){    int               listenfd;    int               n;    const int         on = 1;    struct addrinfo   hints;     struct addrinfo * res;    struct addrinfo * ressave;    bzero(&hints, sizeof(struct addrinfo));    hints.ai_flags = AI_PASSIVE;    hints.ai_family = AF_UNSPEC;    hints.ai_socktype = SOCK_STREAM;    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0) {        printf("host_serv error for %s, %s: %s\n",                (host == NULL) ? "(no hostname)" : host,                (serv == NULL) ? "(no servname)" : serv,                gai_strerror(n));        exit(1);    }    ressave = res;    do {        listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);        if (listenfd == -1) {            continue;  /* error, try next one */        }        if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,                        &on, sizeof(on)) == -1) {            err_exit("setsockopt error");        }        if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0) {            break;  /* success */        }        /* bind error, close and try next one */        if (close(listenfd) == -1) {            err_exit("close error");        }    } while ((res = res->ai_next) != NULL);    if (res == NULL) {  /* errno from final socket() or bind() */        printf("tcp_listen error for %s, %s\n", host, serv);        exit(1);    }    if (listen(listenfd, LISTENQ) == -1) {        err_exit("listen error");    }    if (addrlenp != NULL) {        *addrlenp = res->ai_addrlen;  /* return size of protocol address */    }    freeaddrinfo(ressave);    return(listenfd);}

#include <netdb.h>#include <strings.h>#include "err_exit.h"int tcp_connect(const char * host, const char * serv){    int               sockfd;    int               n;    struct addrinfo   hints;     struct addrinfo * res;    struct addrinfo * ressave;    bzero(&hints, sizeof(struct addrinfo));    hints.ai_family = AF_UNSPEC;    hints.ai_socktype = SOCK_STREAM;    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0) {        printf("host_serv error for %s, %s: %s\n",                (host == NULL) ? "(no hostname)" : host,                (serv == NULL) ? "(no servname)" : serv,                gai_strerror(n));        exit(1);    }    ressave = res;    do {        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);        if (sockfd == -1) {            continue;  /* ignore this one */        }        if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) {            break;  /* success */        }        if (close(sockfd) == -1) {            err_exit("close error");        }    } while ((res = res->ai_next) != NULL);    freeaddrinfo(ressave);    if (res == NULL) {  /* errno set from final connect() */        printf("tcp_connect error for %s, %s\n", host, serv);        exit(1);    }    return(sockfd);}

#include <time.h>#include <netdb.h>#include "err_exit.h"#include "sock_ntop.h"#include "tcp_listen.h"#define MAXLINE 4096int main(int argc, char ** argv){    int                      n;    int                      listenfd;    int                      connfd;    socklen_t                len;    socklen_t                addrlen;    char                     buff[MAXLINE];    time_t                   ticks;    struct sockaddr_storage  cliaddr;    if (argc == 2) {        listenfd = tcp_listen(NULL, argv[1], &addrlen);    }    else if (argc == 3) {        listenfd = tcp_listen(argv[1], argv[2], &addrlen);    }    else {        printf("usage: daytimetcpsrv2 [ <host> ] <service or port>\n");        exit(1);    }    for ( ; ; ) {        len = sizeof(cliaddr);        if ((connfd = accept(listenfd, (struct sockaddr *)&cliaddr,                             &len)) == -1) {            err_exit("accept error");        }        printf("connection from %s\n",                sock_ntop((struct sockaddr *)&cliaddr, len));        ticks = time(NULL);        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));        n = strlen(buff);        if (write(connfd, buff, n) != n) {            err_exit("write error");        }        if (close(connfd) == -1) {            err_exit("close error");        }    }}

#include <netdb.h>#include "err_exit.h"#include "sock_ntop.h"#include "tcp_connect.h"#define MAXLINE 4096int main(int argc, char ** argv){    int                       sockfd;    int                       n;    char                    * paddr;    char                      recvline[MAXLINE + 1];    socklen_t                 len;    struct sockaddr_storage   ss;    if (argc != 3) {        printf("usage: daytimetcpcli <hostname/IPaddress> <service/port#>\n");        exit(1);    }    sockfd = tcp_connect(argv[1], argv[2]);    len = sizeof(ss);    if (getpeername(sockfd, (struct sockaddr *)&ss, &len) == -1) {        err_exit("getpeername error");    }    if ((paddr = sock_ntop((struct sockaddr *)&ss, len)) == NULL) {        err_exit("sock_ntop error");    }    printf("connected to %s\n", paddr);    while ((n = read(sockfd, recvline, MAXLINE)) > 0) {        recvline[n] = '\0';  /* null terminate */        if (fputs(recvline, stdout) == EOF) {            err_exit("fputs error");        }    }    if (n < 0) {        err_exit("read error");    }    exit(0);}

#include <netdb.h>#include <strings.h>#include "err_exit.h"int udp_client(const char * host, const char * serv,            struct sockaddr ** saptr, socklen_t * lenp){    int               sockfd;    int               n;    struct addrinfo   hints;     struct addrinfo * res;    struct addrinfo * ressave;    bzero(&hints, sizeof(struct addrinfo));    hints.ai_family = AF_UNSPEC;    hints.ai_socktype = SOCK_DGRAM;    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0) {        printf("host_serv error for %s, %s: %s\n",                (host == NULL) ? "(no hostname)" : host,                (serv == NULL) ? "(no servname)" : serv,                gai_strerror(n));        exit(1);    }    ressave = res;    do {        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);        if (sockfd != -1) {            break;  /* success */        }    } while ((res = res->ai_next) != NULL);    if (res == NULL) {  /* errno set from final socket() */        printf("udp_client error for %s, %s\n", host, serv);    }    if ((*saptr = (struct sockaddr *)malloc(res->ai_addrlen)) == NULL) {        err_exit("malloc error");    }    memcpy(*saptr, res->ai_addr, res->ai_addrlen);    if (lenp != NULL) {        *lenp = res->ai_addrlen;    }    freeaddrinfo(ressave);    return(sockfd);}

#include <netdb.h>#include <strings.h>#include "err_exit.h"int udp_server(const char * host, const char * serv, socklen_t * addrlenp){    int               sockfd;    int               n;    struct addrinfo   hints;     struct addrinfo * res;    struct addrinfo * ressave;    bzero(&hints, sizeof(struct addrinfo));    hints.ai_flags = AI_PASSIVE;    hints.ai_family = AF_UNSPEC;    hints.ai_socktype = SOCK_DGRAM;    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0) {        printf("host_serv error for %s, %s: %s\n",                (host == NULL) ? "(no hostname)" : host,                (serv == NULL) ? "(no servname)" : serv,                gai_strerror(n));        exit(1);    }    ressave = res;    do {        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);        if (sockfd == -1) {            continue;  /* error - try next one */        }        if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0) {            break;  /* success */        }        if (close(sockfd) == -1) {  /* bind error - close and try next one */            err_exit("close error");        }    } while ((res = res->ai_next) != NULL);    if (res == NULL) {  /* errno from final socket() or bind() */        printf("udp_server error for %s, %s\n", host, serv);        exit(1);    }    if (addrlenp != NULL) {        *addrlenp = res->ai_addrlen;  /* return size of protocol address */    }    freeaddrinfo(ressave);    return(sockfd);}

#include <netdb.h>#include <strings.h>#include "err_exit.h"int udp_connect(const char * host, const char * serv){    int               sockfd;    int               n;    struct addrinfo   hints;     struct addrinfo * res;    struct addrinfo * ressave;    bzero(&hints, sizeof(struct addrinfo));    hints.ai_family = AF_UNSPEC;    hints.ai_socktype = SOCK_DGRAM;    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0) {        printf("host_serv error for %s, %s: %s\n",                (host == NULL) ? "(no hostname)" : host,                (serv == NULL) ? "(no servname)" : serv,                gai_strerror(n));        exit(1);    }    ressave = res;    do {        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);        if (sockfd == -1) {            continue;  /* ignore this one */        }        if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) {            break;  /* success */        }        if (close(sockfd) == -1) {            err_exit("close error");        }    } while ((res = res->ai_next) != NULL);    if (res == NULL) {  /* errno set from final connect() */        printf("udp_connect error for %s, %s\n", host, serv);    }    freeaddrinfo(ressave);    return(sockfd);}

#include <time.h>#include <netdb.h>#include "err_exit.h"#include "sock_ntop.h"#include "udp_server.h"#define MAXLINE 4096int main(int argc, char ** argv){    int                       sockfd;    ssize_t                   n;    char                    * paddr;    char                      buff[MAXLINE];    time_t                    ticks;    socklen_t                 len;    struct sockaddr_storage   cliaddr;    if (argc == 2) {        sockfd = udp_server(NULL, argv[1], NULL);    }    else if (argc == 3) {        sockfd = udp_server(argv[1], argv[2], NULL);    }    else {        printf("usage: daytimeudpsrv [ <host> ] <service or port>\n");        exit(1);    }    for ( ; ; ) {        len = sizeof(cliaddr);        n = recvfrom(sockfd, buff, MAXLINE, 0,                      (struct sockaddr *)&cliaddr, &len);        if ((paddr = sock_ntop((struct sockaddr *)&cliaddr, len)) == NULL) {            printf("sock_ntop error");        }        printf("datagram from %s\n", paddr);        ticks = time(NULL);        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));        n = strlen(buff);        if (sendto(sockfd, buff, n, 0, (struct sockaddr *)&cliaddr, len) != n) {            err_exit("sendto error");        }    }}

#include <netdb.h>#include "err_exit.h"#include "sock_ntop.h"#include "udp_client.h"#define MAXLINE 4096int main(int argc, char ** argv){    int               sockfd;    int               n;    char            * paddr;    char              recvline[MAXLINE + 1];    socklen_t         salen;    struct sockaddr * sa;    if (argc != 3) {        printf("usage: daytimeudpcli1 <hostname/IPaddress> <service/port#>\n");        exit(1);    }    sockfd = udp_client(argv[1], argv[2], &sa, &salen);    if ((paddr = sock_ntop(sa, salen)) == NULL) {        err_exit("sock_ntop error");    }    printf("sending to %s\n", paddr);    if (sendto(sockfd, "", 1, 0, sa, salen) != 1) {  /* send 1-byte datagram */        err_exit("sendto error");    }    if (n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL) < 0) {        err_exit("recvfrom error");    }    recvline[n] = '\0';  /* null terminate */    if (fputs(recvline, stdout) == EOF) {        err_exit("fputs error");    }    exit(0);}


原创粉丝点击