• linux下获取本机IP


    转载: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) ",
                                   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 ");
      return 1;
     }
     /* 调用gethostbyname()。调用结果都存在hptr中 */
     if( (hptr = gethostbyname(hostname) ) == NULL )
     {
      printf("gethostbyname error for host:%s ", hostname);
      return 0; /* 如果调用gethostbyname发生错误,返回1 */
     }
     /* 将主机的规范名打出来 */
     printf("official hostname:%s ",hptr->h_name);
     /* 主机可能有多个别名,将所有别名分别打出来 */
     for(pptr = hptr->h_aliases; *pptr != NULL; pptr++)
      printf("  alias:%s ",*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 ", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
       break;
      default:
       printf("unknown address type ");
       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,这是怎么回事?虽然电脑都有双网卡)

  • 相关阅读:
    通过securecrt跳板机登录linux服务器
    python2.x提示这个错误:UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position
    使用python requests库写接口自动化测试--记录学习过程中遇到的坑(1)
    linux 中文乱码解决
    工作中常用到的命令
    LR学习文档整理
    Django入门示例之被解放的姜戈——02 庄园疑云(数据库及模型)
    Django入门示例之被解放的姜戈——01 初试天涯(安装及启动)
    格式化字符串format函数
    Python之print 格式化输出
  • 原文地址:https://www.cnblogs.com/yunsicai/p/3530158.html
Copyright © 2020-2023  润新知