<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    struct ifreq結構體與ip,子網掩碼,網關等信息

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    總結一下,今天學習的關于通過socket,ioctl來獲得ip,netmask等信息,其中很多內容參照了很多網上的信息,我會一一列出的

    我用的這個函數,就是下面這個函數,其中的有一些全局變量,很好懂,也就不多做解釋了
    一。下面對這個函數進行注解一下:

    int get_nic_IP_Address()//獲取各網卡IP地址、子網掩碼
    {
     struct ifreq ifreq;  //聲明一個struct ifreq結構體(這個結構體中有很多重要的參數,具體可以參照第二的補充)
       int sock;
     int i;
     int tmpint;
     read_dev(); //這個函數的功能是獲得網卡名字(保存在下面提到的sys_nic_ip[][]數組中)并計算網卡總數(就是下面的sys_nic_count)

     for (i=0;i<sys_nic_count;i++)
     {
         if((sock=socket(AF_INET,SOCK_STREAM,0))<0){  //建立一個套接字
             perror("socket");
             return ;
            }
         strcpy(ifreq.ifr_name,sys_nic_name[i]);   //把網卡名字復制到ifreq結構體中的name變量(感覺這個地方是必須的)
         if(ioctl(sock,SIOCGIFADDR,&ifreq)<0) {   //這里涉及ioctl函數對于網絡文件的控制(下面會介紹)
           sprintf(sys_nic_ip[i],"Not set");
         } else {
           sprintf(sys_nic_ip[i],"%d.%d.%d.%d",      //把ip地址提取出來,保存(理解一下socketaddr_in和socketaddr的關系)
           (unsigned char)ifreq.ifr_addr.sa_data[2],
           (unsigned char)ifreq.ifr_addr.sa_data[3],
           (unsigned char)ifreq.ifr_addr.sa_data[4],
           (unsigned char)ifreq.ifr_addr.sa_data[5]);
         }
         if(ioctl(sock,SIOCGIFNETMASK,&ifreq)<0) {  //我的理解是這個地方用SIOCGIFNETMASK,那么ifreq中原本是存的ip地址,現在存成了子網掩碼了。。
           sprintf(sys_nic_mask[i],"Not set");       //把子網掩碼提取出來(但得到的只是超網的劃分方式就是/xx)
         } else {
           sprintf(sys_nic_mask[i],"%d",
           Count((unsigned char)ifreq.ifr_netmask.sa_data[2])+
           Count((unsigned char)ifreq.ifr_netmask.sa_data[3])+
           Count((unsigned char)ifreq.ifr_netmask.sa_data[4])+
           Count((unsigned char)ifreq.ifr_netmask.sa_data[5]));
           
         }
     }
    }
    列出上面最后調用函數(Count())和一些全副變量:
    char sys_nic_ip[20][20];//各網卡IP
    char sys_nic_mask[20][20];//各網卡子網掩碼"/xx"

    int countTable[256] =
    {
    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 
    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
    };
    int Count(int v)

      return countTable[v]; 
    }
    應該理解了吧。。。挺經典的。。。不過網上的貌似就有一個版本。。。很是氣惱

    二。對涉及的知識點進行補充

    1.struct ifreq {
        char ifr_name[IFNAMSIZ];
         union
          {
            struct sockaddr ifru_addr;
            struct sockaddr ifru_dstaddr;
            struct sockaddr ifru_broadaddr;
            struct sockaddr ifru_netmask;
            struct sockaddr ifru_hwaddr;
            short int ifru_flags;
            int ifru_ivalue;
            int ifru_mtu;
            struct ifmap ifru_map;
            char ifru_slave[IFNAMSIZ]; /* Just fits the size */
            char ifru_newname[IFNAMSIZ];
            __caddr_t ifru_data;
          } ifr_ifru;
    };

    # define ifr_name ifr_ifrn.ifrn_name /* interface name */
    # define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
    # define ifr_addr ifr_ifru.ifru_addr /* address */
    # define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
    # define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
    # define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
    # define ifr_flags ifr_ifru.ifru_flags /* flags */
    # define ifr_metric ifr_ifru.ifru_ivalue /* metric */
    # define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
    # define ifr_map ifr_ifru.ifru_map /* device map */
    # define ifr_slave ifr_ifru.ifru_slave /* slave device */
    # define ifr_data ifr_ifru.ifru_data /* for use by interface */
    # define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
    # define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
    # define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */
    # define ifr_newname ifr_ifru.ifru_newname /* New name */
    # define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
    # define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
    # define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)


    2.ioctl 函數 (在網絡中的作用)
    關于這個網絡相關的請求,就是ioctl在這里面起的作用和各個參數的作用。。。可以參照這個網頁,講解的很詳細:
    http://www.iteye.com/topic/309442
    本例中用的2個ioctl控制函數。。上面已經解釋很清楚了

    3.關于socketaddr_in和socketaddr的關系,下面貼出具體的定義:
    struct sockaddr_in 

    short int sin_family; /* 地址族 */ 
    unsigned short int sin_port; /* 端口號 */ 
    struct in_addr sin_addr; /* IP地址 */ 
    unsigned char sin_zero[8]; /* 填充0 以保持與struct sockaddr同樣大小 */ 
    };

    struct sockaddr 

    unsigned short sa_family; /* 地址族, AF_xxx */ 
    char sa_data[14]; /* 14 字節的協議地址 */ 
    };

    比較一下,會發現長度一樣,所以這2個可以通用的,不過要進行類型轉換,比較一下就得出了為什么上面程序中可以用:
    (unsigned char)ifreq.ifr_addr.sa_data[2],這種形式了,還是解釋一下吧:這個ifr_addr是一個struct sockaddr結構體。它其中的sa_date[2]是不是照著上面sockaddr_in中的sin_add(也就是ip地址呢),該明白了吧。。。。

    總結:通過這個函數,可以很好的理解怎么得到ip和子網掩碼的過程。。。。

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全