zoukankan      html  css  js  c++  java
  • Linux C 网络编程

    获取本地 ip 地址,mac,通过域名获取对应的 ip,

    是网络编程可能遇到的比较常见的操作了,所以总结如下(封装了3个函数),

    直接上代码

     
      1 #include <stdio.h>  
      2 #include <stdlib.h>  
      3 #include <string.h>  
      4 #include <errno.h>  
      5 #include <unistd.h>  
      6   
      7 #include <netdb.h>  
      8 #include <net/if.h>  
      9 #include <arpa/inet.h>  
     10 #include <sys/ioctl.h>  
     11 #include <sys/types.h>  
     12 #include <sys/socket.h>  
     13   
     14 #define MAC_SIZE    18  
     15 #define IP_SIZE     16  
     16   
     17 // function declare  
     18 int get_ip_by_domain(const char *domain, char *ip); // 根据域名获取ip  
     19 int get_local_mac(const char *eth_inf, char *mac); // 获取本机mac  
     20 int get_local_ip(const char *eth_inf, char *ip); // 获取本机ip  
     21   
     22   
     23 /****** main test **********/  
     24 int main(void)  
     25 {  
     26     char ip[IP_SIZE];  
     27     char mac[MAC_SIZE];  
     28     const char *test_domain = "www.baidu.com";  
     29     const char *test_eth = "eth0";  
     30   
     31     get_ip_by_domain(test_domain, ip);  
     32     printf("%s ip: %s
    ", test_domain, ip);  
     33   
     34     get_local_mac(test_eth, mac);  
     35     printf("local %s mac: %s
    ", test_eth, mac);  
     36   
     37     get_local_ip(test_eth, ip);  
     38     printf("local %s ip: %s
    ", test_eth, ip);  
     39   
     40     return 0;  
     41 }  
     42   
     43 // 根据域名获取ip  
     44 int get_ip_by_domain(const char *domain, char *ip)  
     45 {  
     46     char **pptr;  
     47     struct hostent *hptr;  
     48   
     49     hptr = gethostbyname(domain);  
     50     if(NULL == hptr)  
     51     {  
     52         printf("gethostbyname error for host:%s/n", domain);  
     53         return -1;  
     54     }  
     55   
     56     for(pptr = hptr->h_addr_list ; *pptr != NULL; pptr++)  
     57     {  
     58         if (NULL != inet_ntop(hptr->h_addrtype, *pptr, ip, IP_SIZE) )  
     59         {  
     60             return 0; // 只获取第一个 ip  
     61         }  
     62     }  
     63   
     64     return -1;  
     65 }  
     66   
     67 // 获取本机mac  
     68 int get_local_mac(const char *eth_inf, char *mac)  
     69 {  
     70     struct ifreq ifr;  
     71     int sd;  
     72       
     73     bzero(&ifr, sizeof(struct ifreq));  
     74     if( (sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)  
     75     {  
     76         printf("get %s mac address socket creat error
    ", eth_inf);  
     77         return -1;  
     78     }  
     79       
     80     strncpy(ifr.ifr_name, eth_inf, sizeof(ifr.ifr_name) - 1);  
     81   
     82     if(ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)  
     83     {  
     84         printf("get %s mac address error
    ", eth_inf);  
     85         close(sd);  
     86         return -1;  
     87     }  
     88   
     89     snprintf(mac, MAC_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",  
     90         (unsigned char)ifr.ifr_hwaddr.sa_data[0],   
     91         (unsigned char)ifr.ifr_hwaddr.sa_data[1],  
     92         (unsigned char)ifr.ifr_hwaddr.sa_data[2],   
     93         (unsigned char)ifr.ifr_hwaddr.sa_data[3],  
     94         (unsigned char)ifr.ifr_hwaddr.sa_data[4],  
     95         (unsigned char)ifr.ifr_hwaddr.sa_data[5]);  
     96   
     97     close(sd);  
     98       
     99     return 0;  
    100 }  
    101   
    102   
    103 // 获取本机ip  
    104 int get_local_ip(const char *eth_inf, char *ip)  
    105 {  
    106     int sd;  
    107     struct sockaddr_in sin;  
    108     struct ifreq ifr;  
    109   
    110     sd = socket(AF_INET, SOCK_DGRAM, 0);  
    111     if (-1 == sd)  
    112     {  
    113         printf("socket error: %s
    ", strerror(errno));  
    114         return -1;        
    115     }  
    116   
    117     strncpy(ifr.ifr_name, eth_inf, IFNAMSIZ);  
    118     ifr.ifr_name[IFNAMSIZ - 1] = 0;  
    119       
    120     // if error: No such device  
    121     if (ioctl(sd, SIOCGIFADDR, &ifr) < 0)  
    122     {  
    123         printf("ioctl error: %s
    ", strerror(errno));  
    124         close(sd);  
    125         return -1;  
    126     }  
    127   
    128     memcpy(&sin, &ifr.ifr_addr, sizeof(sin));  
    129     snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));  
    130   
    131     close(sd);  
    132     return 0;  
    133 }  

    测试运行

    结果如下:

    ifreq 结构体分析和使用:

     1 struct ifreq
     2 {
     3 #define IFHWADDRLEN 6
     4  union
     5  {
     6   char ifrn_name[IFNAMSIZ];  
     7  } ifr_ifrn;
     8  
     9  union {
    10   struct sockaddr ifru_addr;
    11   struct sockaddr ifru_dstaddr;
    12   struct sockaddr ifru_broadaddr;
    13   struct sockaddr ifru_netmask;
    14   struct  sockaddr ifru_hwaddr;
    15   short ifru_flags;
    16   int ifru_ivalue;
    17   int ifru_mtu;
    18   struct  ifmap ifru_map;
    19   char ifru_slave[IFNAMSIZ]; 
    20   char ifru_newname[IFNAMSIZ];
    21   void __user * ifru_data;
    22   struct if_settings ifru_settings;
    23  } ifr_ifru;
    24 };
    25 
    26 #define ifr_name ifr_ifrn.ifrn_name 
    27 #define ifr_hwaddr ifr_ifru.ifru_hwaddr 
    28 #define ifr_addr ifr_ifru.ifru_addr 
    29 #define ifr_dstaddr ifr_ifru.ifru_dstaddr 
    30 #define ifr_broadaddr ifr_ifru.ifru_broadaddr 
    31 #define ifr_netmask ifr_ifru.ifru_netmask 
    32 #define ifr_flags ifr_ifru.ifru_flags 
    33 #define ifr_metric ifr_ifru.ifru_ivalue 
    34 #define ifr_mtu  ifr_ifru.ifru_mtu 
    35 #define ifr_map  ifr_ifru.ifru_map 
    36 #define ifr_slave ifr_ifru.ifru_slave 
    37 #define ifr_data ifr_ifru.ifru_data 
    38 #define ifr_ifindex ifr_ifru.ifru_ivalue 
    39 #define ifr_bandwidth ifr_ifru.ifru_ivalue    
    40 #define ifr_qlen ifr_ifru.ifru_ivalue 
    41 #define ifr_newname ifr_ifru.ifru_newname 
    42 #define ifr_settings ifr_ifru.ifru_settings 

    基本介绍: 

    ifreq结构定义在/usr/include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的。其中包含了一个接口的名 字和具体内容——(是个共用体,有可能是IP地址,广播地址,子网掩码,MAC号,MTU或其他内容)。ifreq包含在ifconf结构中。而 ifconf结构通常是用来保存所有接口的信息的。

    举例说明:

    在Linux系统中,ifconfig命令是通过ioctl接口与内核通信,例如,当系统管理员输入如下命令来改变接口eth0的MTU大小:

        ifconfig eth0 mtu 1250

    ifconfig命令首先打开一个socket,然后通过系统管理员输入的参数初始化一个数据结构,并通过ioctl调用将数据传送到内核。SIOCSIFMTU是命令标识符。

        struct ifreq data;
        fd = socket(PF_INET, SOCK_DGRAM, 0);
        < ... initialize "data" ...>
        err = ioctl(fd, SIOCSIFMTU, &data);

  • 相关阅读:
    Neo4j电影关系图Cypher
    Neo4j电影关系图
    Neo4j配置文件neo4j.conf
    SpringBoot实现多数据源(实战源码)
    Maven添加Oracle驱动及依赖
    HttpClient发送Json数据到指定接口
    java手动分页处理
    设计模式之模板方法模式
    JDBC插入性能优化对比
    Oracle数据库常用监控语句
  • 原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/6425860.html
Copyright © 2011-2022 走看看