转载: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. NuGet学习笔记(2) 使用图形化界面打包自己的类库

    上文NuGet学习笔记(1) 初识NuGet及快速安装使用说到NuGet相对于我们最重要的功能是能够搭建自己的NuGet服务器,实现公司内部类库的轻松共享更新.在安装好NuGet扩展后,我们已经能够通 ...

  2. Linux内核装载和启动一个可执行程序

    “平安的祝福 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 理解编 ...

  3. Apache Tomcat配置

  4. Zookeeper 初体验之——伪分布式安装(转)

    原文地址: http://blog.csdn.net/salonzhou/article/details/47401069 简介 Apache Zookeeper 是由 Apache Hadoop 的 ...

  5. JSON详解以及可以把javabean转换成json串的json-lib应用

    JSON 1. json是什么 它是js提供的一种数据交换格式! 2. json的语法 {}:是对象! 属性名必须使用双引号括起来!单引不行!!! 属性值:null,数值,字符串,数组:使用[]括起来 ...

  6. Loadrunner中关联的作用:

    获取并保存变化的request值{1.sessionid;2.获取上个请求的响应值,用于下个请求参数} 作为检查点 脚本调试工具

  7. static之用法

    本文转载于http://www.cnblogs.com/stoneJin/archive/2011/09/21/2183313.html 在C语言中,static的字面意思很容易把我们导入歧途,其实它 ...

  8. C#多线程编程总结

    VS2008.C#3.0在WinForm开发中,我们通常不希望当窗体上点了某个按钮执行某个业务的时候,窗体就被卡死了,直到该业务执行完毕后才缓过来.一个最直接的方法便是使用多线程.多线程编程的方式在W ...

  9. 记一次小团队Git实践(下)

    在上篇中,我们已经能基本使用git了,接下来继续更深入的挖掘一下git. 更多的配置自定义信息 除了前面讲的用户名和邮箱的配置,还可以自定义其他配置: # 自定义你喜欢的编辑器,可选 git conf ...

  10. BZOJ 2342 回文串-Manacher

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2342 思路:先跑一遍Manacher求出p[i]为每个位置为中心的回文半径,因为双倍回文串 ...