zoukankan      html  css  js  c++  java
  • c++ 获取本地ip地址

    
    
    最终版本:采用指针传参数,不使用别名形式。
    #include <unistd.h>
    #include <netdb.h>  //gethostbyname
    #include <arpa/inet.h>  //ntohl
    #include <iostream>
    using namespace std;
    
    int get_local_ip(int *ip) {
        char hostname[128];
        int ret = gethostname(hostname, sizeof(hostname));
        if (ret == -1){
            return -1;
        }
        struct hostent *hent;
        hent = gethostbyname(hostname);
        if (NULL == hent) {
            return -1;
        }
        //直接取h_addr_list列表中的第一个地址h_addr
        *ip = ntohl(((struct in_addr*)hent->h_addr)->s_addr);
        //int i;
        //for(i=0; hent->h_addr_list[i]; i++) {
        //    uint32_t u = ntohl(((struct in_addr*)hent->h_addr_list[i])->s_addr);
        //    std::cout << u << std::endl;
        //}
        return 0;
    }
    
    int main() {
    
    
        //10.94.45.25 
        //unsigned long ii = 0l;
    
        //ii |= 25;
        //ii |= 45 << 8;
        //ii |= 94 << 16;
        //ii |= 10 << 24;
    
        //cout << ii << endl;
    
    
    
    
    
        int ip = 0;
        int ret = get_local_ip(&ip);
        if (ret == 0) {
            cout << ip << endl;
        } else {
            cerr << "wrong" << endl;
        }
        return 0;
    }
    
    
    /* vim: set ts=4 sw=4 sts=4 tw=100 */



    /*最终定稿*/

    #include <unistd.h> #include <netdb.h> //gethostbyname #include <arpa/inet.h> //ntohl #include <iostream> using namespace std; int get_local_ip(int& ip) { char hostname[128]; int ret = gethostname(hostname, sizeof(hostname)); if (ret == -1){ return -1; } struct hostent *hent; hent = gethostbyname(hostname); if (NULL == hent) { return -1; } //直接取h_addr_list列表中的第一个地址h_addr ip = ntohl(((struct in_addr*)hent->h_addr)->s_addr); //int i; //for(i=0; hent->h_addr_list[i]; i++) { // uint32_t u = ntohl(((struct in_addr*)hent->h_addr_list[i])->s_addr); // std::cout << u << std::endl; //} return 0; } int main() { //10.94.45.25 //unsigned long ii = 0l; //ii |= 25; //ii |= 45 << 8; //ii |= 94 << 16; //ii |= 10 << 24; //cout << ii << endl; int ip; int ret = get_local_ip(ip); if (ret == 0) { cout << ip << endl; } else { cerr << "wrong" << endl; } return 0; }
    
    
    


    c ip地址知识点:

     struct   sockaddr   {  
                    unsigned   short   sa_family;     
                    char   sa_data[14];     
    
            };  
    sockaddr_in详解
    sa_family是地址家族,一般都是“AF_xxx”的形式。通常大多用的是都是AF_INET,代表地址组
    
    sa_data是14字节协议地址。
    
    sockaddr 是通用的socket地址,具体到Internet   socket,用下面的结构,二者可以进行类型转换  
    
      struct   sockaddr_in   {  
                    short   int   sin_family;     // Address family 一般来说 AF_INET(地址族)PF_INET(协议族 )
                    unsigned   short   int   sin_port;  //sin_port存储端口号(使用网络字节顺序),在linux下,端口号的范围0~65535,同时0~1024范围的端口号已经被系统使用或保留
                    struct   in_addr   sin_addr;     //存储IP地址
                    unsigned   char   sin_zero[8];  //sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节   
            };  
            struct   in_addr就是32位IP地址。  
            struct   in_addr   {  
                    union {
                            struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
                            struct { u_short s_w1,s_w2; } S_un_w;
                            u_long S_addr; //s_addr按照网络字节顺序存储IP地址
                    } S_un;
    
                    #define s_addr  S_un.S_addr
            };   
    
    
    
     
    在C/C++写网络程序的时候,往往会遇到字节的网络顺序和主机顺序的问题。这是就可能用到htons(), ntohl(), ntohs(),htons()这4个函数。
    网络字节顺序与本地字节顺序之间的转换函数:
    #include <arpa/inet.h>
    htonl()--"Host to Network Long"
    ntohl()--"Network to Host Long"
    htons()--"Host to Network Short"
    ntohs()--"Network to Host Short"
    
    之所以需要这些函数是因为计算机数据表示存在两种字节顺序:NBO与HBO
    
    网络字节顺序NBO(Network Byte Order): 按从高到低的顺序存储,在网络上使用统一的网络字节顺序,可以避免兼容性问题。
    
    主机字节顺序(HBO,Host Byte Order): 不同的机器HBO不相同,与CPU设计有关,数据的顺序是由cpu决定的,而与操作系统无关。
    如 Intel x86结构下, short型数0x1234表示为34 12, int型数0x12345678表示为78 56 34 12  
    如 IBM power PC结构下, short型数0x1234表示为12 34, int型数0x12345678表示为12 34 56 78
       
    由于这个原因不同体系结构的机器之间无法通信,所以要转换成一种约定的数序,也就是网络字节顺序,其实就是如同power pc那样的顺序. 
    在PC开发中有ntohl和htonl函数可以用来进行网络字节和主机字节的转换.
    这个数据结构是这样的: 
       struct hostent { 
       char *h_name; 
       char **h_aliases; 
       int h_addrtype; 
       int h_length; 
       char **h_addr_list; 
       }; 
       #define h_addr h_addr_list[0]  
    这里是这个数据结构的详细资料:  
    struct hostent:  
      h_name – 地址的正式名称。 
      h_aliases – 空字节-地址的预备名称的指针。 
      h_addrtype –地址类型; 通常是AF_INET。  
      h_length – 地址的比特长度。 
      h_addr_list – 零字节-主机网络地址指针。网络字节顺序。 
      h_addr - h_addr_list中的第一地址。 
    gethostbyname() 成功时返回一个指向结构体 hostent 的指针,或者 是个空 (NULL) 指针。(但是和以前不同,不设置errno,h_errno 设置错 误信息。请看下面的 herror()。) 但是如何使用呢? 这个函数可不象它看上去那么难用。 
    这里是个例子: 
    #include <stdio.h> 
      #include <stdlib.h> 
      #include <errno.h> 
      #include <netdb.h> 
      #include <sys/types.h> 
      #include <netinet/in.h> 
    int main(int argc, char *argv[]) 
       { 
       struct hostent *h; 
    if (argc != 2) { /* 检查命令行 */ 
       fprintf(stderr,"usage: getip address
    "); 
       exit(1); 
       } 
    if ((h=gethostbyname(argv[1])) == NULL) { /* 取得地址信息 */ 
       herror("gethostbyname"); 
       exit(1); 
       } 
    printf("Host name : %s
    ", h->h_name); 
      printf("IP Address : %s
    ",inet_ntoa(*((struct in_addr *)h->h_addr))); 
    return 0; 
       } 
    在使用 gethostbyname() 的时候,你不能用perror() 打印错误信息 (因为 errno 没有使用),你应该调用 herror()。
    相当简单,你只是传递一个保存机器名的字符串(例如 "whitehouse.gov") 给gethostbyname(),然后从返回的数据结构 

    struct hostent 中获取信息。 唯一也许让人不解的是输出 IP 地址信息。h->h_addr 是一个 char *,
    但是 inet_ntoa() 需要的是 struct in_addr。因此,我转换 h->h_addr 成 struct in_addr *,然后得到数据。
    
    
    

    ============================================================
    参考地址:http://blog.csdn.net/liuqinstudy/article/details/8813932
    #include
    <stdio.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <unistd.h> #include <sys/types.h> #include <netdb.h> #include <net/if.h> #include <arpa/inet.h> #include <iostream> using namespace std; int get_local_ip(unsigned long& ip) { int sfd, intr; struct ifreq buf[16]; struct ifconf ifc; sfd = socket(AF_INET, SOCK_DGRAM, 0); if (sfd < 0) return -1; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = (caddr_t)buf; if (ioctl(sfd, SIOCGIFCONF, (char *)&ifc)) return -1; intr = ifc.ifc_len / sizeof(struct ifreq); while (intr-- > 0 && ioctl(sfd, SIOCGIFADDR, (char *)&buf[intr])); close(sfd); ip = ntohl(((struct sockaddr_in*)(&buf[intr].ifr_addr))->sin_addr.s_addr); return 0; } int main() { unsigned long ip = 0; int ret = get_local_ip(ip); if (ret == 0) { cout << ip << endl; } else { cout << "err" << endl; } return 0; }
  • 相关阅读:
    String前后去掉空格、option只能定义value值吗?还能添加什么值。dom和Jquery对象转换。
    JsonObject没有fromObject、idea引入maven有红线没依赖、JsonObject maven 依赖包
    json几个小例子
    [极客大挑战 2019]PHP1
    栈溢出原理笔记(一)
    CentOS7怎么安装图形界面
    快速搭建WordPress博客
    Mac 安装Mysql 之 Sqlservice 区别
    Metasploit-初篇
    Windows To Go 制作详解
  • 原文地址:https://www.cnblogs.com/i80386/p/4673801.html
Copyright © 2011-2022 走看看