在Linux下擷取多個ip地址(轉載)

來源:互聯網
上載者:User
 

原始碼級Unix/Linux 通用網卡IP地址擷取方法

主要通過這兩個函數:gethostname()和gethostbyname()

 

int gethostname(char *name, size_t namelen);

DESCRIPTION

The gethostname() function shall return the standard host name for the current machine. The namelen argument shall specify the size of the array pointed to by the name argument. The returned name shall be null-terminated, except that if namelen is an insufficient length to hold the host name, then the returned name shall be truncated and it is unspecified whether the returned name is null-terminated.

Host names are limited to {HOST_NAME_MAX} bytes.

struct hostent *gethostbyname(const char *name);
這個函數的傳入值是網域名稱或者主機名稱,例如"www.google.com","wpc"等等。
傳出值,是一個hostent的結構(如下)。如果函數調用失敗,將返回NULL。

struct hostent {
  char  *h_name;
  char  **h_aliases;
  int   h_addrtype;
  int   h_length;
  char  **h_addr_list;
  };
解釋一下這個結構:
其中,
  char *h_name 表示的是主機的規範名。例如www.google.com的規範名其實是www.l.google.com
  char   **h_aliases 表示的是主機的別名。www.google.com就是google他自己的別名。有的時候,有的主機可能有好幾個別名,這些,其實都是為了易於使用者記憶而為自己的網站多取的名字。
  int   h_addrtype 表示的是主機ip地址的類型,到底是ipv4(AF_INET),還是ipv6(AF_INET6)
  int   h_length 表示的是主機ip地址的長度
  int   **h_addr_lisst 表示的是主機的ip地址,注意,這個是以網路位元組序儲存的。千萬不要直接用printf帶%s參數來打這個東西,會有問題的哇。所以到真正需要列印出這個IP的話,需要調用inet_ntop()。

const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) :
這個函數,是將類型為af的網路地址結構src,轉換成主機序的字串形式,存放在長度為cnt的字串中。
這個函數,其實就是返回指向dst的一個指標。如果函數調用錯誤,傳回值是NULL。

 

下面是常式,有詳細的注釋。

#include <stdio.h>
#include <arpa/inet.h>  //for inet_ntop()

#include <unistd.h>  //for gethostname()
#include <netdb.h>       //for gethostbyname()
#include <sys/socket.h>

int main(int argc, char **argv)
{
 char **pptr;
 struct hostent *hptr;
 char hostname[32];
 char str[32];
 
 if(gethostname(hostname,sizeof(hostname)) )
 {
  printf("gethostname calling error/n");
  return 1;
 }
 /* 調用gethostbyname()。調用結果都存在hptr中 */
 if( (hptr = gethostbyname(hostname) ) == NULL )
 {
  printf("gethostbyname error for host:%s/n", hostname);
  return 0; /* 如果調用gethostbyname發生錯誤,返回1 */
 }
 /* 將主機的規範名打出來 */
 printf("official hostname:%s/n",hptr->h_name);
 /* 主機可能有多個別名,將所有別名分別打出來 */
 for(pptr = hptr->h_aliases; *pptr != NULL; pptr++)
  printf("  alias:%s/n",*pptr);
 /* 根據地址類型,將地址打出來 */
 switch(hptr->h_addrtype)
 {
  case AF_INET:
  case AF_INET6:
   pptr=hptr->h_addr_list;
   /* 將剛才得到的所有地址都打出來。其中調用了inet_ntop()函數 */
   for(;*pptr!=NULL;pptr++)
    printf("  address:%s/n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
   break;
  default:
   printf("unknown address type/n");
   break;
 }
 return 0;
}

運行輸出結果:

official hostname:localhost.localdomain
  alias:localhost
  address:127.0.0.1

(給出的這個ip好像沒什麼意義,在另外一台機器上運行,給出ip是:192.168.0.3,而ifconfig給出的ip是192.168.2.100,這是怎麼回事?雖然電腦都有雙網卡)

在Unix和Linux系統下有兩種方法可以獲得系統IP地址(gethostbyname和ioctl)

gethostbyname通過網域名稱解析擷取對應電腦的網路地址,ioctl是一系列的網路函數獲得原生IP

(推薦使用ioctl方法,這個方法能給出的ip與ifconfig命令顯示的ip一致,並且能不經修改的在arm板上正常運行。而gethostname()聯合gethostbyname()方法給出的ip與ifconfig給出的並不一致,無法使用[還不懂為什麼],並且在arm板上不能正確運行。)ioctl範常式序
#include <stdio.h>
#include <sys/types.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <linux/sockios.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>

int main(void)
{
       int s;
       struct ifconf conf;
       struct ifreq *ifr;
       char buff[BUFSIZ];
       int num;
       int i;

       s = socket(PF_INET, SOCK_DGRAM, 0);
       conf.ifc_len = BUFSIZ;
       conf.ifc_buf = buff;

       ioctl(s, SIOCGIFCONF, &conf);
       num = conf.ifc_len / sizeof(struct ifreq);
       ifr = conf.ifc_req;

       for(i=0;i < num;i++)
       {
               struct sockaddr_in *sin = (struct sockaddr_in *)(&ifr->ifr_addr);

               ioctl(s, SIOCGIFFLAGS, ifr);
               if(((ifr->ifr_flags & IFF_LOOPBACK) == 0) && (ifr->ifr_flags & IFF_UP))
               {
                       printf("%s (%s)/n",
                               ifr->ifr_name,
                               inet_ntoa(sin->sin_addr));
               }
               ifr++;
       }
}

輸出:

eth1 (10.60.68.127)     第二種方法:(不推薦,雖然代碼稍微簡單,有效運行場合尚未明確)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.