第六章 名字与IP地址转换
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
6.3 IP地址转换函数(1)
IP地址通常有以下几种形式
点分十进制IP地址,如202.113.29.19 unsigned long型主机字节顺序(网络ID+主机ID) unsigned long型网络字节顺序(套接字地址中的 成员) 域名(需进行域名解析)
地址转换时所需的.h文件
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>
struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr sin_addr; unsigned char sin_zero[8]; } struct in_addr { unsigned long s_addr;};
6.3 IP地址转换函数(8)
对应的主机ID
IP值 44.135.86.12 127.0.0.1 172.16.23.95 192.168.9.1 IP分类 A A B C
网络ID
16进制表示 0087560C 00000001 0000175F 00000001
主机ID
点分10进制 0.135.86.12 0.0.0.1 0.0.23.95 0.0.0.1
6.4 IP和域名的转换(2)
#include <netdb.h>
任意主机名转换为IP地址
原型:struct hostent *gethostbyname(char *name); 说明:name可以是主机名或IP地址 返回值:成功返回hostent指针,否则返回NULL,并设errno值 struct hostent { char *h_name; /*主机正式名称*/ char **h_aliases; /*主机的别名列表*/ int h_addrtype; /*主机地址类型*/ int h_length; /*主机地址长度,IPv4是4字节32位地址*/ char **h_addr_list;}; /*主机的IP地址列表*/ #define h_addr h_addr_list[0] /*主机的第一个IP地址*/
6.3 IP地址转换函数(7)
网络字节顺序
无网络位的主机ID(主机字节顺序)
unsigned long inet_lnaof(struct in_addr addr) 功能:将网络字节顺序地址转换为无网络位的主机ID,比 inet_network()后在根据网络类型屏蔽网络位简单 返回值:返回32位的无网络位的主机ID 注意:不必知道网络类型,可直接得到无网络位的主机ID 用法:struct sockaddr_in addr; unsigned long host_id; host_id=inet_lnaof(addr.sin_addr); 比较: unsigned long net_addr,host_addr; host_addr=inet_network(“202.113.29.8”)&0x000000FF; (必须知道子网掩码,如C类网)
6.3 IP地址转换函数(2)
点分十进制IP地址
网络字节顺序地址
unsigned long inet_addr(char *string) 功能:将十进制点分格式的IP地址(字符串)转换为套接字中可用 的网络字节顺序地址(32位无符号长整型) 返回值:若IP地址有效,返回网络字节顺序地址;否则,返回 INADDR_NONE 注意:返回INADDR_NONE时,并没有建立一个有效的errno值 用法:struct sockaddr_in servaddr; servaddr.sin_addr.s_addr=inet_addr(“202.113.29.8”); 实例: 改写tcpserver.cpp server.sin_addr.s_addr=htonl(INADDR_ANY); 改为 server.sin_addr.s_addr= inet_addr(“202.113.29.19”);
名字解析方式
查询本机文件/etc/hosts:较大网络维护困难。 网络信息系统(NIS):用于本地/内部网络。 域名系统(DNS):广泛应用于Internet。
6.2 套接口地址(1)
套接字地址结构
(1)struct sockaddr 通用套接字地址结构
struct sockaddr { unsigned short sa_family; char sa_data[14]; };
6.3 IP地址转换函数(9)
网络字节顺序地址
无主机位的网络ID
unsigned long inet_netof(struct in_addr addr) 功能:将网络字节顺序地址转换为无主机位的网络ID, inet_lnaof()伙伴。 返回值:返回32位无主机位的网络ID 注意:返回值是右对齐的,主机位可能被移出(见下表) 用法:struct sockaddr_in addr; unsigned long net_id; net_id=inet_netof(addr.sin_addr);
6.3 IP地址转换函数(11)
主机ID和网络ID 合并为网络字节顺序地址
struct in_addr inet_makeaddr(unsigned long net, unsigned long host) 功能:将主机ID和网络ID合并生成新的IP地址 返回值:返回值放在struct in_addr结构中,它也是套接字地 址的成员 实例:makeaddr.cpp % ./makeaddr 44.135.86.12:net=0x0000002c host=0x0087560c inet_makeaddr:44.135.86.12 127.0.0.1:net=0x0000007f host=0x00000001 inet_makeaddr:127.0.0.1 ……
6.4 IP和域名的转换(3)
典型代码:
struct hostent *hp; struct sockaddr_in addr; hp=gethostbyname(“”); addr.sin_addr=*((struct in_addr *)hp->h_addr);
6.3 IP地址转换函数(6)
网络字节顺序地址
IP地址
char *inet_ntoa(struct in_addr addr) 功能:将网络字节顺序地址转换为十进制点分格式的IP地址 返回值:返回指向十进制点分格式字符串指针 用法:struct sockaddr_in addr; cout<<“IP address:” <<inet_ntoa(addr.sin_addr)<<endl; 实例: 参见tcpserver.cpp
6.4 IP和域名的转换(1)
#include <sys/utsname.h>
获取当前主机名
原型:int gethostname(char *name,int len) 说明: name接收主机名的缓冲区, len为接收缓冲区最大长度 返回值:成功返回0,否则-1,errno置错误值
获取当前主机域名
6.3 IP地址转换函数(3)
int inet_aton(char *string,struct in_addr *addr) 功能:将十进制点分格式的IP地址(字符串)转换为套接字中可用 的网络字节顺序地址(struct in_addr类型)。 返回值:若成功,返回非零,否则0,也没建立一个有效的errno值 用法:struct sockaddr_in servaddr; if(!inet_aton(“202.113.29.8”,&servaddr.sin_addr)) { cout<<“bad address\n”; exit(0); } 实例: 改写tcpserver.cpp程序, 将inet_addr()函数用 inet_aton()实现。
字节顺序转换函数
#include <sys/types.h> #include <netinet/in.h> unsigned long htonl(unsigned long hostlong ) unsigned short htons(unsigned short hostshort) unsigned long ntohl(unsigned long netlong) unsigned short ntohs(unsigned short netlong)
原型:int getdomainname(char *name,int len) 说明: name接收域名的缓冲区, len为接收缓冲区最大长度 返回值:成功返回0,否则-1,errno置错误值 实例 gethostn.cpp %./gethostn Hostname=„math‟ Domainname=„(none)‟
6.3 IP地址转换函数(5)
实例: network.cpp 主机字节顺序 网络字节顺序 %./network 44.135.86.12=0x2c87560c net 0x0c56872c 127.0.0.1=0x7f000001 net 0x0100007f 172.16.23.95=0xac10175f net 0x5f1710ac 192.168.9.1= 0xc0a80901 net 0x0109a8c0 说明: 在这个例子中,对输出格式进行了设置 #include <iomanip.h> … cout<<setfill(„0‟); cout<<hex<<setw(8)<<addr;
6.3 IP地址转换函数(4)
点分十进制IP地址
பைடு நூலகம்
主机字节顺序地址
unsigned long inet_network(char *addr) 功能:将十进制点分格式的IP地址(字符串)转换为主机字节顺序 地址.其结果与网络掩码运算后可得到网络地址和主机地址 返回值:成功返回主机字节顺序的32位二进制IP地址,否则返回 0xFFFFFFFF 注意:以主机字节顺序的地址才可以保证用户安全地使用网络掩 码。主机字节顺序的地址和网络掩码(如255.255.255.0)进 行按位与运算(即屏蔽掉主机位),可以得到无主机位的网 络位;若屏蔽掉网络位,则得到无网络位的主机地址。但必 须事先知道网络类型。 用法:unsigned long net_addr,host_addr; net_addr=inet_network(“202.113.29.8”)&0xFFFFFF00; host_addr=inet_network(“202.113.29.8”)&0x000000FF; 分别得到网络位和主机位地址。
6.3 IP地址转换函数(10)
对应的网络ID
IP值
44.135.86.12 127.0.0.1 172.16.23.95 192.168.9.1
IP分类
A A B C
16进制表示
0000002C 0000007F 0000AC10 00C0A809
点分10进制
0.0.0.44 0.0.0.127 0.0.172.16 0.192.168.9
sa_family
sa_data[14]
(2)struct sockaddr_in IPv4套接字地址结构
sin_family= AF_INET
sin_port
sin_addr sin_zero[8]
6.2 套接口地址(2)
可以看出:
通用套接口地址没什么用处,只提供一种参考模型。很 多函数原型中的参数为该类型。 指向以上两种类型的指针可以通用。
第六章 名字和IP地址转换
名字解析 套接字地址 IP地址转换函数 IP和域名转换函数 套接字信息函数
6.1名字解析
名字服务原理
提供地址映射机制:包括域名名字服务和端口名字服务 域名 IP地址 端口、协议 服务名 便于记忆 屏蔽细节(哪台主机、几个IP、服务名对应端口号等) 提供协议无关性(IPv4协议使用32位IP地址、IPv6协议 使用128位IP地址,便于移植)