博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux下获取本机IP
阅读量:5811 次
发布时间:2019-06-18

本文共 3675 字,大约阅读时间需要 12 分钟。

转载:http://blog.chinaunix.net/uid-20593763-id-1620213.html

源代码级Unix/Linux 通用网卡IP地址获取方法

在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)
 
 
 
 
 
第二种方法:(不推荐,虽然代码稍微简单,有效运行场合尚未明确)

主要通过这两个函数: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);

这个函数的传入值是域名或者主机名,例如""等等。
传出值,是一个hostent的结构(如下)。如果函数调用失败,将返回NULL。

struct hostent {

  char  *h_name;
  char  **h_aliases;
  int   h_addrtype;
  int   h_length;
  char  **h_addr_list;
  };
解释一下这个结构:
其中,
  char *h_name 表示的是主机的规范名。例如的规范名其实是。
  char   **h_aliases 表示的是主机的别名。就是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,这是怎么回事?虽然电脑都有双网卡)

转载于:https://www.cnblogs.com/yunsicai/p/3530158.html

你可能感兴趣的文章
spring-boot支持websocket
查看>>
菜鸟笔记(一) - Java常见的乱码问题
查看>>
我理想中的前端工作流
查看>>
记一次Git异常操作:将多个repository合并到同一repository的同一分支
查看>>
CodeIgniter 3.0 新手捣鼓源码(一) base_url()
查看>>
Chrome 广告屏蔽功能不影响浏览器性能
查看>>
vSphere 6将于2月2日全球同步发表
查看>>
Android状态栏实现沉浸式模式
查看>>
让你的APP实现即时聊天功能
查看>>
iOS 绝对路径和相对路径
查看>>
使用Openfiler搭建ISCSI网络存储
查看>>
应用新安全组 - 每天5分钟玩转 OpenStack(116)
查看>>
4.3. 键盘设置
查看>>
iOS - UIViewController
查看>>
IntPtr 转 string
查看>>
学生名单
查看>>
(转) 多模态机器翻译
查看>>
【官方文档】Nginx负载均衡学习笔记(三) TCP和UDP负载平衡官方参考文档
查看>>
矩阵常用归一化
查看>>
Oracle常用函数总结
查看>>