国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C++ > 正文

c/c++實(shí)現(xiàn)獲取域名的IP地址

2020-05-23 14:13:09
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

本文給大家匯總介紹了使用c/c++實(shí)現(xiàn)獲取域名的IP地址的幾種方法以及這些方法的核心函數(shù)gethostbyname的詳細(xì)用法,非常的實(shí)用,有需要的小伙伴可以參考下。

c/c++實(shí)現(xiàn)獲取域名的IP地址

 

 
  1. // GetHostIP.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。 
  2. // 
  3.  
  4. #include "stdafx.h" 
  5.  
  6. #include <winsock2.h> 
  7. #include <ws2tcpip.h> 
  8. #include <stdio.h> 
  9. #include <windows.h> 
  10. #pragma comment(lib, "ws2_32.lib") 
  11.  
  12. int main(int argc, char **argv) 
  13.  
  14. //----------------------------------------- 
  15. // Declare and initialize variables 
  16. /* 
  17. * WSADATA結(jié)構(gòu)被用來(lái)儲(chǔ)存調(diào)用AfxSocketInit全局函數(shù)返回的Windows Sockets初始化信息。 
  18. * 這個(gè)結(jié)構(gòu)被用來(lái)存儲(chǔ)被WSAStartup函數(shù)調(diào)用后返回的Windows Sockets數(shù)據(jù)。它包含Winsock.dll執(zhí)行的數(shù)據(jù)。 
  19. */ 
  20. WSADATA wsaData; 
  21. int iResult; 
  22.  
  23. DWORD dwError; /*每個(gè)word為2個(gè)字節(jié)的長(zhǎng)度,DWORD 雙字即為4個(gè)字節(jié),每個(gè)字節(jié)是8位*/ 
  24. int i = 0; 
  25.  
  26. struct hostent *remoteHost; /*域名*/ 
  27. char *host_name; /*主機(jī)名*/ 
  28. struct in_addr addr; /*ip*/ 
  29.  
  30. char **pAlias; 
  31.  
  32. // Validate the parameters 
  33. if (argc != 2) { 
  34. printf("usage: GetHostIP hostname/n"); 
  35. return 1; 
  36. // 此處應(yīng)添加的程序如下 
  37. // 1. 當(dāng)初始化winsocket 
  38. iResult = WSAStartup(MAKEWORD(2,2),&wsaData);/* & 取地址*/ 
  39. // 2. 檢查該socket是否初始化成功,即該socket是否等于0;如果初始化不成功,應(yīng)當(dāng)給出錯(cuò)誤報(bào)警,并結(jié)束程序。 
  40. if(iResult!=0){ 
  41. printf("初始化失敗!/n"); 
  42. return 1; 
  43.  
  44. /////////////////結(jié)束/////////////////////////////////// 
  45.  
  46.  
  47. host_name = argv[1]; 
  48. printf("Calling gethostbyname with %s/n", host_name); 
  49. // 此處應(yīng)添加的程序如下 
  50. // 1. 利用函數(shù)gethostbyname(),獲取給定主機(jī)名的指針。 
  51. remoteHost = gethostbyname(host_name); 
  52. // 2. 應(yīng)當(dāng)熟悉該結(jié)構(gòu)指針的結(jié)構(gòu) 
  53. // 其中該函數(shù)申明如下:struct hostent* gethostbyname(const char *name) 
  54.  
  55.  
  56. // 此處應(yīng)添加的程序如下 
  57. // 1. 如果上面函數(shù)返回的主機(jī)結(jié)構(gòu)指針為空(NULL),則做如下處理: 
  58. // a. 利用函數(shù) int WSAGetLastError ( void ) 檢查當(dāng)前是否發(fā)生網(wǎng)絡(luò)錯(cuò)誤, 
  59. // b. 返回的發(fā)生的錯(cuò)誤類型并作相應(yīng)的處理,比如,若沒(méi)有找到主機(jī)的錯(cuò)誤(此時(shí)該函數(shù)返回WSAHOST_NOT_FOUND) 
  60. if(remoteHost == NULL){ 
  61. //printf("gethostbynameError:%d",WSAGetLastError()); 
  62. return 1; 
  63. }else
  64. // 2. 如果返回的主機(jī)指針不為空,則做如下處理: 
  65. // a. 打印出如下參數(shù):主機(jī)名和IP地址,若該主機(jī)對(duì)應(yīng)于多個(gè)ip地址,應(yīng)當(dāng)分別列出。 
  66. printf("主機(jī)名:%s/n",remoteHost->h_name); 
  67. for(i=0;;i++){ 
  68. if(remoteHost->h_addr_list[i]!=0) 
  69. /*從緩存中把 p 拷貝到addr中 
  70. *同時(shí)addr.S_un.Saddr 
  71. * in_addr ipAddr;  
  72. * ipAddr.S_un.S_addr = inet_addr("127.0.0.1");  
  73. * 就是把字符串形式的ip地址轉(zhuǎn)化為0xXXXXXXXX形式的地址格式。 
  74. */ 
  75. addr.s_addr = *(u_long*)remoteHost->h_addr_list[i];  
  76. printf("ip #%d:%s/n",i,inet_ntoa(addr)); /* inet_ntoa() 函數(shù)將網(wǎng)絡(luò)地址轉(zhuǎn)成二進(jìn)制的數(shù)字相關(guān)函數(shù):inet_aton, inet_ntoa */ 
  77. /* 
  78. for(i=0;;i++){ 
  79. char *p = remoteHost->h_addr_list[i]; 
  80. if(p==NULL) break; 
  81. /*從緩存中把 p 拷貝到addr中 
  82. *同時(shí)addr.S_un.Saddr 
  83. * in_addr ipAddr;  
  84. * ipAddr.S_un.S_addr = inet_addr("127.0.0.1");  
  85. * 就是把字符串形式的ip地址轉(zhuǎn)化為0xXXXXXXXX形式的地址格式。 
  86. * 
  87. memcpy(&addr.S_un.S_addr,p,remoteHost->h_length);  
  88. printf("ip地址為:%s/n",inet_ntoa(addr)); 
  89.  
  90. */ 
  91.  
  92.  
  93.  
  94.  
  95.  
  96. // 此處應(yīng)添加的程序如下 
  97. // 程序完成后應(yīng)當(dāng)適當(dāng)測(cè)試,需要進(jìn)行的測(cè)試如下: 
  98. // 1. 測(cè)試主機(jī)結(jié)構(gòu)指針獲取失敗 
  99. // 2. 測(cè)試包含多個(gè)IP地址的主機(jī) 
  100. // 3. 你能想到的任何可能出現(xiàn)的異常情況 
  101. /////////////////結(jié)束/////////////////////////////////// 
  102.  
  103.  
  104. system("pause"); /*防止窗體關(guān)閉函數(shù)*/ 
  105. return 0; 

下面給大家詳細(xì)介紹下上面代碼的核心gethostbyname的詳細(xì)用法

使用這個(gè)東西,首先要包含2個(gè)頭文件:

 

 
  1. #include <netdb.h> 
  2. #include <sys/socket.h> 
  3. struct hostent *gethostbyname(const char *name); 

這個(gè)函數(shù)的傳入值是域名或者主機(jī)名,例如"www.google.com","wpc"等等。

傳出值,是一個(gè)hostent的結(jié)構(gòu)(如下)。如果函數(shù)調(diào)用失敗,將返回NULL。

 

 
  1. struct hostent { 
  2. char *h_name; 
  3. char **h_aliases; 
  4. int h_addrtype; 
  5. int h_length; 
  6. char **h_addr_list; 
  7. }; 

解釋一下這個(gè)結(jié)構(gòu), 其中:

char *h_name表示的是主機(jī)的規(guī)范名。例如www.google.com的規(guī)范名其實(shí)是www.l.google.com。

char **h_aliases表示的是主機(jī)的別名。www.google.com就是google他自己的別名。有的時(shí)候,有的主機(jī)可能有好幾個(gè)別名,這些,其實(shí)都是為了易于用戶記憶而為自己的網(wǎng)站多取的名字。

int h_addrtype表示的是主機(jī)ip地址的類型,到底是ipv4(AF_INET),還是ipv6(AF_INET6)

int h_length表示的是主機(jī)ip地址的長(zhǎng)度

int **h_addr_lisst表示的是主機(jī)的ip地址,注意,這個(gè)是以網(wǎng)絡(luò)字節(jié)序存儲(chǔ)的。千萬(wàn)不要直接用printf帶%s參數(shù)來(lái)打這個(gè)東西,會(huì)有問(wèn)題的哇。所以到真正需要打印出這個(gè)IP的話,需要調(diào)用inet_ntop()。

const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) :

這個(gè)函數(shù),是將類型為af的網(wǎng)絡(luò)地址結(jié)構(gòu)src,轉(zhuǎn)換成主機(jī)序的字符串形式,存放在長(zhǎng)度為cnt的字符串中。

這個(gè)函數(shù),其實(shí)就是返回指向dst的一個(gè)指針。如果函數(shù)調(diào)用錯(cuò)誤,返回值是NULL。

下面是例程,有詳細(xì)的注釋。

 

 
  1. #include <netdb.h> 
  2. #include <sys/socket.h> 
  3. int main(int argc, char **argv) 
  4. char *ptr,**pptr; 
  5. struct hostent *hptr; 
  6. char str[32]; 
  7. /* 取得命令后第一個(gè)參數(shù),即要解析的域名或主機(jī)名 */ 
  8. ptr = argv[1]; 
  9. /* 調(diào)用gethostbyname()。調(diào)用結(jié)果都存在hptr中 */ 
  10. if( (hptr = gethostbyname(ptr) ) == NULL ) 
  11. printf("gethostbyname error for host:%s/n", ptr); 
  12. return 0; /* 如果調(diào)用gethostbyname發(fā)生錯(cuò)誤,返回1 */ 
  13. /* 將主機(jī)的規(guī)范名打出來(lái) */ 
  14. printf("official hostname:%s/n",hptr->h_name); 
  15. /* 主機(jī)可能有多個(gè)別名,將所有別名分別打出來(lái) */ 
  16. for(pptr = hptr->h_aliases; *pptr != NULL; pptr++) 
  17. printf(" alias:%s/n",*pptr); 
  18. /* 根據(jù)地址類型,將地址打出來(lái) */ 
  19. switch(hptr->h_addrtype) 
  20. case AF_INET: 
  21. case AF_INET6: 
  22. pptr=hptr->h_addr_list; 
  23. /* 將剛才得到的所有地址都打出來(lái)。其中調(diào)用了inet_ntop()函數(shù) */ 
  24. for(;*pptr!=NULL;pptr++) 
  25. printf(" address:%s/n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str))); 
  26. break
  27. default
  28. printf("unknown address type/n"); 
  29. break
  30. return 0; 

另外附上獲得公網(wǎng)與內(nèi)網(wǎng)ip的代碼:

 

 
  1. bool getPublicIp(string& ip) 
  2. int sock; 
  3. char **pptr = NULL; 
  4. struct sockaddr_in destAddr; 
  5. struct hostent *ptr = NULL; 
  6. char destIP[128]; 
  7.  
  8. sock = socket(AF_INET,SOCK_STREAM,0); 
  9. if( -1 == sock ){ 
  10. perror("creat socket failed"); 
  11. return false
  12. bzero((void *)&destAddr,sizeof(destAddr)); 
  13. destAddr.sin_family = AF_INET; 
  14. destAddr.sin_port = htons(80); 
  15. ptr = gethostbyname("www.ip138.com"); 
  16. if(NULL == ptr){ 
  17. perror("gethostbyname error"); 
  18. return false
  19. for(pptr=ptr->h_addr_list ; NULL != *pptr ; ++pptr){ 
  20. inet_ntop(ptr->h_addrtype,*pptr,destIP,sizeof(destIP)); 
  21. printf("addr:%s/n",destIP); 
  22. ip = destIP; 
  23. return true
  24. return true

獲取內(nèi)網(wǎng)IP

 

 
  1. int getlocalip(char* outip) 
  2. #ifndef WIN32 
  3. int i=0; 
  4. int sockfd; 
  5. struct ifconf ifconf; 
  6. char buf[512]; 
  7. struct ifreq *ifreq; 
  8. char* ip; 
  9. //初始化ifconf 
  10. ifconf.ifc_len = 512; 
  11. ifconf.ifc_buf = buf; 
  12. strcpy(outip,"127.0.0.1"); 
  13. if((sockfd = socket(AF_INET, SOCK_DGRAM, 0))<0) 
  14. return -1; 
  15. ioctl(sockfd, SIOCGIFCONF, &ifconf); //獲取所有接口信息 
  16. close(sockfd); 
  17. //接下來(lái)一個(gè)一個(gè)的獲取IP地址 
  18. ifreq = (struct ifreq*)buf; 
  19. for(i=(ifconf.ifc_len/sizeof(struct ifreq)); i>0; i--) 
  20. ip = inet_ntoa(((struct sockaddr_in*)&(ifreq->ifr_addr))->sin_addr); 
  21.  
  22.  
  23. if(strcmp(ip,"127.0.0.1")==0) //排除127.0.0.1,繼續(xù)下一個(gè) 
  24. ifreq++; 
  25. continue
  26. strcpy(outip,ip); 
  27. return 0; 
  28. #else 
  29. return 0; 
  30. #endif 
  31.  


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 广德县| 神木县| 上杭县| 米脂县| 太仆寺旗| 临湘市| 靖宇县| 灵宝市| 彰武县| 安阳县| 宜春市| 巴林右旗| 昌吉市| 治县。| 尚志市| 宣威市| 赤峰市| 大关县| 琼中| 建平县| 武定县| 探索| 定州市| 桦甸市| 农安县| 夏河县| 会东县| 忻城县| 郎溪县| 昆明市| 当阳市| 原平市| 普安县| 松溪县| 体育| 松江区| 峡江县| 新河县| 景洪市| 诸暨市| 安新县|