编程接口指南

主机名和服务名

接口 getaddrinfo(3SOCKET)getnameinfo(3SOCKET)gai_strerror(3SOCKET) 以及 freeaddrinfo(3SOCKET) 提供了一种在主机上的服务名称与地址之间进行转换的简化方法。这些接口比 getipnodebyname(3SOCKET)gethostbyname(3NSL) 以及 getservbyname(3SOCKET) API 更新。将透明地处理 IPv6 和 IPv4 地址。

getaddrinfo(3SOCKET) 例程返回指定主机名和服务名的组合地址和端口号。由于会动态分配 getaddrinfo(3SOCKET) 所返回的信息,因此必须通过 freeaddrinfo(3SOCKET) 释放信息以防止内存泄漏。getnameinfo(3SOCKET) 返回与指定地址和端口号关联的主机名和服务名。调用 gai_strerror(3SOCKET) 以便基于 getaddrinfo(3SOCKET)getnameinfo(3SOCKET) 所返回的 EAI_xxx 代码列显错误消息。

以下是使用 getaddrinfo(3SOCKET) 的示例。

    struct addrinfo         *res, *aip;

    struct addrinfo         hints;

    int                     error;



    /* Get host address.  Any type of address will do. */

    bzero(&hints, sizeof (hints));

    hints.ai_flags = AI_ALL|AI_ADDRCONFIG;

    hints.ai_socktype = SOCK_STREAM;



    error = getaddrinfo(hostname, servicename, &hints, &res);

    if (error != 0) {

      (void) fprintf(stderr, "getaddrinfo: %s for host %s service %s\n",

      gai_strerror(error), hostname, servicename);

     return (-1);

    }

 

res 指向的结构中处理完 getaddrinfo(3SOCKET) 所返回的信息之后,应该通过 freeaddrinfo(res) 释放存储空间。

getnameinfo(3SOCKET) 例程在确定错误原因时特别有用,如以下示例所示:

    struct sockaddr_storage faddr;

    int                     sock, new_sock, sock_opt;

    socklen_t               faddrlen;

    int                     error;

    char                    hname[NI_MAXHOST];

    char                    sname[NI_MAXSERV];



     ...

         faddrlen = sizeof (faddr);

         new_sock = accept(sock, (struct sockaddr *)&faddr, &faddrlen);

         if (new_sock == -1) {

             if (errno != EINTR && errno != ECONNABORTED) {

                 perror("accept");

             }

             continue;

         }        

         error = getnameinfo((struct sockaddr *)&faddr, faddrlen, hname, 

                     sizeof (hname), sname, sizeof (sname), 0);

         if (error) {

           (void) fprintf(stderr, "getnameinfo: %s\n",

                       gai_strerror(error));

         } else {

             (void) printf("Connection from %s/%s\n", hname, sname);

         }