struct-hostent *gethostbyname(const char *name)详解
来源:互联网 发布:查看数据库有哪些用户 编辑:程序博客网 时间:2024/05/19 21:16
struct hostent *gethostbyname(const char *name);
gethostbyname函数根据域名解析出服务器的ip地址,它返回一个结构体struct hostent:
<span style="font-size:12px;">#include <netdb.h>struct hostent {char *h_name; /* official name of host */char **h_aliases; /* alias list */int h_addrtype; /* host address type */int h_length; /* length of address */char **h_addr_list; /* list of addresses */}#define h_addr h_addr_list[0] /* for backward compatibility */</span>
除了服务器的ip地址外,这个结构体还包含了更多服务器的信息,有:
char *h_name
This is the “official” name of the host.
char **h_aliases
These are alternative names for the host, represented as a null-terminated vector of strings.
主机的可选名字,以NULL做为结束标记
int h_addrtype
This is the host address type; in practice, its value is always either AF_INET or AF_INET6, with the latter being used for IPv6 hosts. In principle other kinds of addresses could be represented in the database as well as Internet addresses; if this were done, you might find a value in this field other than AF_INET or AF_INET6. See Socket Addresses.
int h_length
This is the length, in bytes, of each address.
ip地址的长度,ipv4对应4个字节
char **h_addr_list
This is the vector of addresses for the host. (Recall that the host might be connected to multiple networks and have different addresses on each one.) The vector is terminated by a null pointer.
一般主机可以有多个ip地址,比如www.163.com就有121.14.228.43和121.11.151.72两个ip,h_addr_list就用来
保存多个ip地址
char *h_addr
This is a synonym for h_addr_list[0]; in other words, it is the first host address.
即为h_addr_list[0],表示第一个地址,这个符号其实是兼容老系统而存在的
我们写一个程序来获取主机www.163.com的详细信息:
<span style="font-size:12px;">#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/socket.h>#define SERVPORT 80int main(int argc, char **argv){ int i, sockfd; struct hostent *host; struct sockaddr_in serv_addr; if ((host = gethostbyname(argv[1])) == NULL) { printf("gethostbyname error\n"); exit(0); } printf("official name: %s\n\n", host->h_name); printf("address length: %d bytes\n\n", host->h_length); printf("host name alias: \n"); for (i = 0; host->h_aliases[i]; i++) { printf("%s\n", host->h_aliases[i]); } printf("\naddress list: \n"); for (i = 0; host->h_addr_list[i]; i++) { if ((sockfd = socket(AF_INET, SOCK_STREAM,0)) == -1) { printf("socket error\n"); exit(0); } // 先清零,然后用struct sockaddr_in来填值 bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(SERVPORT); /* h_addr_list[i]指向in_addr类型 */ serv_addr.sin_addr = *((struct in_addr *)host->h_addr_list[i]); const char *ip = inet_ntoa(serv_addr.sin_addr); printf("connect to %s ", ip); // 系统调用的时候,把sockaddr_in转换成sockaddr if (connect(sockfd, (struct sockaddr *)&serv_addr, \ sizeof(struct sockaddr)) == -1) { printf("error\n"); exit(0); } printf("success\n"); } return 0;}</span>
运行结果如下:
这个程序首先调用gethostbyname得到服务器的各种信息,其中就包含它拥有的ip地址,保存在h_addr_list中,然后
对于h_addr_list中的每个ip地址,都调用connect连接其80端口。h_addr_list保存的ip地址类型是char *,
struct sockaddr_in中sin_addr的类型是struct in_addr,而程序中却直接把h_addr_list[i]强制转换成struct in_addr *
serv_addr.sin_addr = *((struct in_addr *)host->h_addr_list[i]);
这是没有问题的,因为h_addr_list保存的并不是真正的字符串,而是指向struct in_addr类型的指针。
另外,struct in_addr用来表示ip地址,本质上是一个long类型,刚好4个字节。然后我们调用inet_ntoa把它转换
成可读性更强的dots-and-number字符串。关于ip地址和dots-and-number字符串之间的转换有4个函数:
#include <arpa/inet.h>/* network to ascii */char *inet_ntoa(struct in_addr in); /* ascii to network */int inet_aton(const char *cp, struct in_addr *inp);const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);int inet_pton(int af, const char *src, void *dst); /* presentation format to network */
inet_ntoa和inet_aton不支持ipv6, 据说迟早要废除,不过目前来说,很多系统都可以看见这两个函数
- struct-hostent *gethostbyname(const char *name)详解
- gethostbyname和struct hostent详解
- gethostbyname和struct hostent详解
- gethostbyname && struct hostent 示例
- gethostbyname的返回值类型struct hostent
- struct hostent 结构体与gethostbyname(),gethostbyaddr
- gethostbyname的返回值类型struct hostent
- Struct hostent
- static inline int register_chrdev(unsigned int major, const char *name, const struct file_operations
- struct hostent结构体
- struct hostent结构体
- struct hostent结构体
- struct hostent结构体
- struct hostent结构体
- struct hostent结构体
- struct hostent结构体
- struct hostent结构体
- gethostbyname出错,hostent总是为空
- 网络构成要素
- 【java】深入理解异常处理机制
- 【很早以前的作品】自编游戏之NationFight
- kvm虚拟化技术实战记录(3)——编译安装qemu-kvm
- Android程序运行时权限与文件系统权限的区别
- struct-hostent *gethostbyname(const char *name)详解
- 设计模式之单例模式
- new life
- XMPP协议学习笔记
- 从键盘输入三个正整数,判断它们是否构成等腰三角形
- 灰度图像--图像分割 阈值处理之OTSU阈值
- [开发笔记]Visual Assist X破解过程
- uva 10718 Bit Mask (位运算)
- VMware和oracle vm virtualBox哪个更好