一、gethostbyname函数原型
#include <netdb.h> struct hostent *gethostbyname(const char *ghostname); 返回:成功返回非空指针,出错为NULL且设置h_errno
二、hostent结构
struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* pointer to array of pointers to alias name */ int h_addrtype; /* host address type: AF_INET */ int h_length; /* length of address: 4 */ char **h_addr_list; /* ptr to array of ptrs with IPv4 addrs */ };
三、关于全局整体变量h_errno
当gethostbyname发生错误时,它不设置errno变量,而是将全局变量h_errno设置为<netdb.h>中定义的下列常值之一:
(1)HOST_NOT_FOUND;
(2)TRY_AGAIN;
(3)NO_RECOVERY;
(4)NO_DATA(等同于NO_ADDRESS)
NO_DATA错误表示指定的名字有效,但是它没有A记录
四、gethostbyname例子
#include <stdio.h> #include <netdb.h> #include <stdlib.h> #include <sys/socket.h> #include <arpa/inet.h> #define INET_ADDRSTRLEN 16 void err_ret(const char *, ...); void err_msg(const char *, ...); 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) { err_msg("gethostbyname error for host: %s: %s", ptr, hstrerror(h_errno)); continue; } printf("official hostname: %s ", hptr->h_name); for (pptr = hptr->h_aliases; *pptr != NULL; pptr++) { printf(" alias: %s ", *pptr); } switch (hptr->h_addrtype) { case AF_INET: { pptr = hptr->h_addr_list; for ( ; *pptr != NULL; pptr++) { printf(" address: %s ", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str))); } break; } default: { err_ret("unknown address type"); break; } } } exit(0); }
#include <stdio.h> #include <errno.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> /* ANSI C header file */ #include <syslog.h> /* for syslog() */ #define MAXLINE 4096 int daemon_proc; /* set nonzero by daemon_init() */ static void err_doit(int, int, const char *, va_list); /* Nonfatal error related to system call * Print message and return */ void err_ret(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, LOG_INFO, fmt, ap); va_end(ap); return; } /* Fatal error related to system call * Print message and terminate */ void err_sys(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, LOG_ERR, fmt, ap); va_end(ap); exit(1); } /* Fatal error related to system call * Print message, dump core, and terminate */ void err_dump(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, LOG_ERR, fmt, ap); va_end(ap); abort(); /* dump core and terminate */ exit(1); /* shouldn't get here */ } /* Nonfatal error unrelated to system call * Print message and return */ void err_msg(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(0, LOG_INFO, fmt, ap); va_end(ap); return; } /* Fatal error unrelated to system call * Print message and terminate */ void err_quit(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(0, LOG_ERR, fmt, ap); va_end(ap); exit(1); } /* Print message and return to caller * Caller specifies "errnoflag" and "level" */ static void err_doit(int errnoflag, int level, const char *fmt, va_list ap) { int errno_save, n; char buf[MAXLINE + 1]; errno_save = errno; /* value caller might want printed */ #ifdef HAVE_VSNPRINTF vsnprintf(buf, MAXLINE, fmt, ap); /* safe */ #else vsprintf(buf, fmt, ap); /* not safe */ #endif n = strlen(buf); if (errnoflag) snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save)); strcat(buf, " "); if (daemon_proc) { syslog(level, buf); } else { fflush(stdout); /* in case stdout and stderr are the same */ fputs(buf, stderr); fflush(stderr); } return; }
五、gethostbyaddr函数原型
#include <netdb.h> struct hostent *gethostbyaddr(const struct in_addr *, socklen_t, int family); 返回:成功为非空指针,否则为NULL且设置h_errno
功能:由一个二进制IP地址找到相应的主机名