一、實驗目的
理解名字與IP地址的轉換函數,實現主機名與IP地址之間的轉換。學習和掌握Linux下的gethostbyname()和gethostbyaddr()函數基本原理和基本編程方法。
二、實驗平臺
ubuntu-8.04操作系統
三、實驗內容
1、利用gethostbyname()函數編程實現名字解析,將主機名轉換成相應IP地址。
2、利用gethostbyaddr()函數編程實現反向地址解析,將IP地址轉換成主機名,查詢指定IP地址對應的主機域名地址。
四、實驗原理
現在的網絡都是使用名字來訪問服務器的,而不是使用IP地址來訪問。那它們是怎么轉換的呢?答案就是利用名字與IP地址的轉換函數實現的:gethostbyname和gethostbyaddr在主機名字與IP地址間進行轉換。
1、gethostbyname()函數
找主機名最基本的函數gethostbyname(),該函數執行如果成功,它返回一個指向結構hostent的指針,該結構中包含了該主機的所有IPv4地址或IPv6地址;如果失敗返回空指針。下面是定義:
------------------------------------------------------------------- # include <netdb.h> struct hostent * gethostbyname (const char *hostname); ------------------------------------------------------------------- |
參數hostname是主機的域名地址,函數將查詢的結果作為參數返回。如果失敗返回空指針;如果成功此參數返回的非空指針指向如下的hostent結構:
------------------------------------------------------------------- struct hostent { char * h_name; /*主機的正式名稱*/ char * * h_aliases; /*主機的別名列表*/ int h_addrtype; /*主機地址類型*/ int h_length; /*主機地址長度*/ char * * h_addr_list; *主機IP地址的列表*/ }; # define h_addr h_addr_list[0] /*在列表中的第一個地址*/ ------------------------------------------------------------------- |
|
2、gethostbyaddr()函數
gethostbyaddr()函數的作用是可以查詢指定的IP地址對應的主機域名地址。函數的形式如下:
------------------------------------------------------------------- # include <netdb.h> struct hostent * gethostbyaddr (const char *addr, size_t len, int family); ------------------------------------------------------------------- |
返回:若為非空指針,則表示成功;若為空指針,則表示出錯,同時設置h_errno。該函數同樣返回一個指向結構hostent的指針。而在參數中,參數addr不是char *類型,而是一個真正指向含有IPv4或IPv6地址的結構in_addr或in6_addr的指針;len是此結構的大小,對于IPv4地址為4,對于IPv6地址為16;參數family為AF_INET或AF_INET6。
五、實驗步驟
1、登陸進入ubuntu操作系統,新建一個文件,命名為gethostbyname.c,新建另一個文件,命名為gethostbyaddr.c。
2、在gethostbyname.c和gethostbyaddr.c中編寫相應代碼并保存。
3、在“終端”(“Applications”→“附件”→“終端”)中執行命令進入gethostbyname.c和gethostbyaddr.c所在目錄。(pwd命令可以顯示當前所在目錄;ls命令可以顯示當前目錄下的文件和文件夾信息;cd..命令可以進入上一級目錄;cd 目錄名 命令可以進入當前所示的某個目錄。)
4、執行命令gcc –o gethostbyname gethostbyname.c生成可執行文件gethostbyname。
5、執行命令./gethostbyname host_name。(注意:此處host_name代表主機名,利用命令hostname可以查看本機的主機名)
6、觀察并分析程序運行結果。
7、執行命令gcc –o gethostbyaddr gethostbyaddr.c生成可執行文件gethostbyaddr。
8、執行命令./gethostbyname 127.0.0.1,觀察結果。
9、認真分析源代碼,體會gethostbyname()和gethostbyaddr()函數的應用。
六、參考程序
1、gethostbyname.c內容如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
-
- main(int argc, const char **argv)
- {
- ulong addr;
- struct hostent*hp;
- char **p;
- if (argc !=2) {
- (void)printf("usage: %s host_name\n", argv[0]);
- exit(1);
- }
- hp =gethostbyname(argv[1]);
- if (hp ==NULL) {
- (void)printf("host information for %s not found\n", argv[1]);
- exit(2);
- }
- for (p =hp->h_addr_list; *p != 0; p++) {
- structin_addr in;
- char**q;
- (void)memcpy(&in.s_addr, *p, sizeof(in.s_addr));
- (void)printf("%s\t%s", inet_ntoa(in), hp->h_name);
- for(q = hp->h_aliases; *q != 0; q++)
- (void) printf(" %s", *q);
- (void)putchar('\n');
- }
- exit (0);
- }
-
2、gethostbyaddr.c內容如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
-
- main(int argc, const char **argv)
- {
- ulong addr;
- structhostent *hp;
- char **p;
- if (argc !=2) {
- (void)printf("usage: %s IP-address\n", argv[0]);
- exit(1);
- }
- if((int)(addr = inet_addr(argv[1])) == -1) {
- (void)printf("IP-address must be of the form a.b.c.d\n");
- exit(2);
- }
- hp =gethostbyaddr((char *)&addr, sizeof (addr), AF_INET);
- if (hp ==NULL) {
- (void)printf("host information for %s not found\n", argv[1]);
- exit(3);
- }
- for (p =hp->h_addr_list; *p != 0; p++) {
- structin_addr in;
- char**q;
- (void)memcpy(&in.s_addr, *p, sizeof (in.s_addr));
- (void)printf("%s\t%s", inet_ntoa(in), hp->h_name);
- for(q = hp->h_aliases; *q != 0; q++)
- (void) printf(" %s", *q);
- (void)putchar('\n');
- }
- exit (0);
- }
-