域名系统
可以通过 ping 命令查看域名对应的 IP 地址。
查看本机的默认 DNS 域名服务器地址可以使用 nslookup 命令。
IP地址和域名之间的转换
程序中有必要使用域名是很有必要的,系统随时可能会因为各种原因导致 IP 地址变更。而域名则比 IP 地址稳定得多,因此编写程序时使用域名要比 IP 地址更好。
客户端可以在程序使用域名和 IP 地址的转换函数,每次运行程序时根据域名获取 IP 地址再接入服务器,这样就不会依赖服务器的 IP 地址了。
利用域名获取IP地址
传入字符串格式的域名即可获取 IP 地址。
#include <netdb.h>
struct hostent* gethostbyname(const char* hostname);
struct hostent* host=gethostbyname(存有域名的字符串);
返回值:包含 IP 地址信息的结构体的指针,失败返回空指针 nullptr
hostent 结构体的定义如下:
struct hostent{
char* h_name; // 官方域名
char** h_aliases; // 绑定的其他域名,同一个 IP 可以绑定多个域名
int h_addrtype; // 结构体中存储的地址所属的地址族,如果是 IPv4 地址,则此变量为 AF_INET
// IP 地址的长度,如果是 IPv4 地址,4个字节,则此变量值为 4, IPv6 ,16 个字节,变量值为16
int h_length;
// 地址列表,最重要的成员。以整数形式(网络字节序)保存域名对应的 IP 地址,可能对应多个 IP ,利用服务器进行负载均衡
char** h_addr_list;
}
注意:h_addr_list
中存储地址的方式是 char*,而 char* 的内容并不是地址值,实际上是 in_addr
结构体的地址。
因此要取得点分十进制字符串格式的地址,需要先将 char* 转换为 in_addr* 类型,然后解引用取得整数地址值,再使用 inet_ntoa 将其转换为点分十进制格式的字符串。
inet_ntoa(*(struct in_addr *)host->h_addr_list[i]));
利用IP地址获取域名
利用 IP 地址获取 host 信息,包括绑定的所有域名及其他 IP 地址
#include <netdb.h>
struct hostent* gethostbyaddr(const char* addr, socklen_t len, int family);
SOCKADDR_IN addr;
memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr=inet_addr(存有IP的字符串);
struct hostent *host = gethostbyaddr((char*)&addr.sin_addr, 4, AF_INET);
返回值:包含 IP 地址信息的结构体的指针,失败返回空指针 nullptr