0.
前段时间做一个项目,需要根据hostname来解析对应的ipaddress,就想到了这个函数gethostbyname。
所以就查找对应函数。
1.
大致流程如下:
应用的头文件:
#include <netdb.h>
函数和数据结构:
struct hostent *gethostbyname(const char *hostname);
此函数返回的非空指针指向下面的hostent结构:
struct hostent {
char *h_name; /*official name of host*/
char **h_aliases; /*pointer to array of pointers to alias names*/
int h_addrtype; /*host address type: AF_INET or AF_INET6*/
int h_length; /*length of address:4 or 16*/
char **h_addr_list; /*ptr to array of ptrs with IPv4 or IPv6 addrs*/
};
#define h_addr h_addr_list[0] /*first address in list*/
特别是最后一个define定义,一定要注意,当时我在结构体里找了半天也没有找到,原来是个宏定义。
3. 需要用到的其他函数:
inet_aton,inet_addr和inet_ntoa在点分十进制数串(如,“192.168.1.10")与他的32位网络字节二进制值之前转换IPV4地址,
有2个比较新的函数inet_pton和inet_ntop,这2个对IPV4和IPV6地址都能处理。
4. 网络字节顺序格式(NBO,Network Byte Order)和主机字节顺序格式(HBO,Host Byte Order)
(一)
在网络传输中,TCP/IP协议在保存IP地址这个32位二进制数时,协议规定采用在低位存储地址中包含数据的高位字节的存储顺序,这种顺序格式就被称为网络字节顺序格式。在实际网络传输时,数据按照每32位二进制数为一组进行传输,由于存储顺序的影响,实际的字节传输顺序是由高位字节到低位字节的传输顺序。
为了使通信的双方都能够理解数据分组所携带的源地址、目的地址以及分组的长度等二进制信息,无论是主机还是路由器,在发送每一个分组以前,都必须将二进制信息转换为TCP/IP标准的网络字节顺序格式。网络字节顺序格式的地址不受主机、路由器类型的影响,它的表示是唯一的。
在Socket编程开发中,通过函数inet_addr和inet_ntoa可以实现点分字符串与网络字节顺序格式IP地址之间的转换。
(二)
主机字节顺序格式顾名思义,其IP地址的格式是和具体主机或者路由器相关的。对于不同的主机,在进行IP地址的存储时有不同的格式,比如对于Motorola 68k系列主机,其HBO与NBO是相同的。而对于Intel x86系列,HBO与NBO则正好相反。
在Socket编程中,有四个函数来完成主机字节顺序格式和网络字节顺序格式之间的转换,它们是:htonl、htons、ntohl、和ntohs。htons和ntohs完成16位无符号数的相互转换,htonl和ntohl完成32位无符号数的相互转换。
在实际应用中我们常见到将端口号转换的例子(如上例)。这是因为,如果用户输入一个数字,而且将指定使用这一数字作为端口号,应用程序则必须在使用它建立地址以前,把它从主机字节顺序转换成网络字节顺序(使用htons()函数),以遵守TCP/IP协议规定的存储标准。相应地,如果应用程序希望显示包含于某一地址中的端口号(例如从getpeername()函数中返回的),这一端口号就必须在被显示前从网络顺序转换到主机顺序(使用ntohs()函数)。