转载: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);
这个函数的传入值是域名或者主机名,例如"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,这是怎么回事?虽然电脑都有双网卡)

linux下获取本机IP的更多相关文章

  1. Linux下获取本机IP地址的代码

    Linux下获取本机IP地址的代码,返回值即为互联网标准点分格式的字符串. #define ETH_NAME "eth0" //获得本机IP地址 char* GetLocalAdd ...

  2. Linux 下获取本机IP

    http://blog.csdn.net/K346K346/article/details/48231933 int main () { /* struct ifaddrs *ifap, *ifa; ...

  3. Windows下获取本机IP地址方法介绍

    Windows下获取本机IP地址方法介绍 if((hostinfo = gethostbyname(name)) != NULL) { #if 1 ; printf("IP COUNT: % ...

  4. Linux下获得本机IP(非127.0.0.1)

    在Linux下用InetAddress.getLocalHost()方法获取本机IP地址,得到的结果总是:127.0.1.1.原来这个是etc/hosts文件中的配置,并非网卡的IP地址. 可用代码如 ...

  5. QT5下获取本机IP地址、计算机名、网络连接名、MAC地址、子网掩码、广播地址

    获取主机名称 /* * 名称:get_localmachine_name * 功能:获取本机机器名称 * 参数:no * 返回:QString */ QString CafesClient::get_ ...

  6. Linux下获取和设置IP

    在Linux下获取关于IP和网关的操作:重点是对struct ifreq 的操作. 那么进入目录/usr/include/net/if.h下看查找struct ifreq结构体. /* Interfa ...

  7. rust下获取本机IP

    又拾起了rust语言, 想写一点东西玩一玩, 但是发现连一个获取本机IP地址的库都没有, 还得挽起袖子自己撸. https://crates.io/crates/local_ipaddress 没有用 ...

  8. python未知网卡名情况下获取本机IP

    import socket def get_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: # doesn't even ...

  9. windows和linux下的本机IP的获取(亲测有效)

    package com.handsight.platform.fras.util; import org.apache.log4j.Logger; import javax.servlet.http. ...

随机推荐

  1. 注解:【有连接表的】Hibernate单向1->1关联

    Person与Address关联:单向1->1,[有连接表的] (使用较少!) Person.java package org.crazyit.app.domain; import javax. ...

  2. ubuntu初始化root帐号密码

    Ubuntu Kylin 14.04的安装过程中并没有提供设置root密码的过程,取而代之的是自定义的帐号. 如果我们需要使用到root帐号或者root权限,则需要重新设置root帐号的密码. 设置方 ...

  3. 在Salesforce中可以对某一个Object的Standard Button或Link进行重写

    在Salesforce中可以对某一个Object的Standard Button或Link进行重写,来实现我们特定的逻辑过程,比如:在删除某个Object之前要判断该Object的某个Field的状态 ...

  4. view和activity的区别

    activity相当于控制部分,view相当于显示部分.两者之间是多对多的关系,所有东西必须用view来显示.  viewGroup继承自view,实现了ViewManager,ViewParent接 ...

  5. Java学习随笔1:Java是值传递还是引用传递?

    Java always passes arguments by value NOT by reference. Let me explain this through an example: publ ...

  6. LoadRunner性能测试执行过程的问题

    LoadRunner做性能测试 从设计到分析执行 执行测试并分析调优: 测试中报错的信息解决: 1. Failed to connect to server "域名:80": [1 ...

  7. psql-06表:约束

    默认值 可以理解为建表时没定义的默认值为null,表示未知,//注意和js中null不一样; 建表时设置 create table child(id int, age int default 18); ...

  8. 标准W3C盒子模型和IE盒子模型

    标准W3C盒子模型和IE盒子模型   CSS盒子模型:网页设计中CSS技术所使用的一种思维模型. CSS盒子模型组成:外边距(margin).边框(border).内边距(padding).内容(co ...

  9. 【分块】【树上莫队】bzoj1086 bzoj3052

    1086 http://vfleaking.blog.163.com/blog/static/174807634201231684436977/ 3052 http://vfleaking.blog. ...

  10. 反射和动态代理实现上下文切入AOP效果

    Java的反射框架提供了动态代理机制,允许在运行期对目标类生成代理,避免重复开发,实现上下文切入的功能. 代码是最好的交流语言: Subject接口 RealSubject实现接口 SubjectHa ...