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