Linux C gethostname, gethostbyname有什么区别?

问题:gethostname, gethostbyname 这2个名字相似的网络编程API,有何联系与区别?

gethostname 获取主机名称(非登录用户名),其参数用于存储查询结果。gethostname 查找的是/etc/hostname文件,得到本主机名。其获得的主机名,可用于getaddrinfo的主机名参数,获取本地主机IP地址。
gethostbyname 获取网络主机项(entry),其参数是主机名。执行的是对DNS系统A记录的查询(或查找本地/etc/host文件), 只能返回IPv4地址。不可重入,其可重入版本是gethostbyname_r。

gethostname 系列函数

gethostname 函数说明

gethostname 获取主机名称
与gethostname相对的,还有sethostname,用于设置主机名称(个人推测sethostname不是可重入的,因为多个线程修改不同主机名,可能导致非预期结果)。

#include <unistd.h>

int gethostname(char *name, size_t len);
int sethostname(const char *name, size_t len);

gethostname得到的host name,等价于$ uname -n命令。
/etc/hostname内容:

ubuntu

$ uname -n命令运行结果

$ uname -n
ubuntu

gethostbyname 系列函数

gethostbyname(), gethostbyaddr(), herror(), hstrerror() 函数已废弃。应用程序应该用getaddrinfo(), getnaminfo(), gai_strerror替代。

gethostbyname*()得到查询主机主机名称name的hostent。hostent 是host entry简写,该结构记录主机的信息,包括主机名、别名、地址类型、地址长度和地址列表。之所以主机的地址是一个列表的形式,原因是当一个主机有多个网络接口时,会有多个地址。

gethostname通常用于通过host name得到地址信息。

#include <netdb.h>
extern int h_errno;

struct hostent *gethostbyname(const char *name);

#include <sys/socket.h>       /* for AF_INET */
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type);
void sethostent(int stayopen);
void endhostent(void);
void herror(const char *s);
const char *hstrerror(int err);

/* System V/POSIX extension */
struct hostent *gethostent(void);

/* GNU extensions */
struct hostent *gethostbyname2(const char *name, int af);
int gethostent_r( struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop);
int gethostbyaddr_r(const void *addr, socklen_t len, int type, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop);
int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop);
int gethostbyname2_r(const char *name, int af, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop);

示例

gethostname获取本地host name,gethostbyname通过host name得到本地ip地址信息。

char name[100];
if (gethostname(name, sizeof(name)) < 0) {
    perror("gethostname error");
    exit(1);
}
printf("host name = %s\n", name);

struct hostent *hp;
if ((hp = gethostbyname(name)) == NULL) {
    perror("gethostbyname error");
    exit(1);
}
int j = 0;
while (hp->h_addr_list[j] != NULL) {
    printf("Official name = %s\n", hp->h_name);
    printf("Alias name = %s\n", hp->h_aliases[j]);
    printf("addr type = %d\n", hp->h_addrtype); /* AF_INET: 2; AF_INET6: 10 */
    printf("ip len = %d bytes\n", hp->h_length); /* IPv4: 4bytes; IPv6: 16bytes */
    printf("ip = %s\n", inet_ntoa(*(struct in_addr *)hp->h_addr_list[j]));
    j++;
}

运行结果

host name = ubuntu
Official name = ubuntu
Alias name = (null)
addr type = 2
ip len = 4 bytes
ip = 127.0.1.1

本地/etc/hosts文件内容如下。可以看到gethostbyname通过本地主机名ubuntu,得到的ip地址与/etc/hosts文件内容一致。

127.0.0.1   localhost
127.0.1.1   ubuntu

参考

  1. Linux getaddrinfo获得本机ip地址为何127.0.1.1?
  2. UNP 学习笔记 #11 名字与地址转换

Linux C gethostname, gethostbyname有什么区别?

上一篇:linux防火墙(下)


下一篇:解决:laravel出现Please provide a valid cache path.