• 用C语言列出Linux或Unix上的网络适配器


    上代码:

    1. #include <sys/socket.h>
    2. #include <stdio.h>
    3. 
    4. #include <netdb.h>
    5. #include <ifaddrs.h>
    6. 
    7. int main() {
    8. 		struct ifaddrs *addresses;
    9. 		if(getifaddrs(&addresses) == -1) {
    10.			 printf("getifaddrs failed");
    11.	         return -1;
    12.     }
    13. 	struct ifaddrs *address = addresses;
    14. 	while(address){
    15. 		int family = address->ifa_addr->sa_family;
    16. 		if(family == AF_INET || family == AF_INET6){
    17.				printf("%s\t",address->ifa_name);
    18.				printf("%s\t",family == AF_INET ? "IPv4":"IPv6");
    19.				char ap[100];
    20.				const int family_size = family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
    21.				getnameinfo(address->ifa_addr, family_size, ap,sizeof(ap),0,0,NI_NUMERICHOST);
    22.				printf("\t%s\n",ap);
    23.			}
    24.         address = address->ifa_next;
    25.	 	}
    26.     freeifaddrs(addresses);
    27.     return 0;
    28. }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    代码解释:

    • sys/socket.h 定义主要socket的操作和结构体,如sockaddr_in、AF_INET(IPv4地址族)、AF_INET6(IPv6地址族)等。

    • stdio.h 提供了通用文件操作的支持和窄字符输入输出的能力,如printf等。

    • netdb.h 这里包含许多对网络操作的定义 ,如addrinfo结构体,这里面有AI_NUMERICHOST,这是说返回数字主机地址作为名字等等。

    • ifaddrs.h 定义ifaddrs结构体和函数 getifaddrs, freeifaddrs。

    • 第8行:声明了 ifaddrs结构体指针,这个结构体:

    struct ifaddrs {
    	//因为ifaddrs是一个链表的数据结构,所以ifa_next是指向下一个节点的指针
    	struct ifaddrs  *ifa_next; 
    	char *ifa_name;    // 接口名称
    	unsigned int ifa_flags;   // SIOCGIFFLAGS的标记,这是与设备io相关的控制标志
    	struct sockaddr *ifa_addr;    //接口地址
    	struct sockaddr *ifa_netmask; //接口网络掩码
    	union { // 联合体
    		struct sockaddr *ifu_broadaddr; // 接口广播地址
            struct sockaddr *ifu_dstaddr; //点到点目的地址
    	} ifa_ifu;
    	#define ifa_broadaddr ifa_ifu.ifu_broadaddr
    	#define ifa_dstaddr ifa_ifu.ifu_dstaddr
    	void *ifa_data;    //地址特定数据
               };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 第9行,getifaddrs函数取回网络适配器数据,这些数据是一个链表,所以将头指针赋给addresses指针变量
    • 第13行,struct ifaddrs *address = addresses; 将取回到指针地址赋给另外一个指针变量address,这样通过新指针address变量来遍历所有的数据,而不改变指针addresses的值。
    • 第15行,int family = address->ifa_addr->sa_family;取回接口地址的地址族。简单来说就是看它是IPv4还是IPv6 。
    • 第21行,getnameinfo函数取回名称
    • 第26行,freeifaddrs(addresses);用于释放指针
      运行的结果大概是这样的:
      请添加图片描述
  • 相关阅读:
    Databend 开源周报第 110 期
    MySQL3:MySQL中一条更新SQL是如何执行的?
    Kotlin高仿微信-第28篇-朋友圈-预览图片、预览小视频
    k8s--基础--08--环境搭建--安装kubernetes的web ui界面
    自己实现 SpringMVC 底层机制 系列之-实现任务阶段 4- 完成自定义@Service 注解功能
    C++11 互斥锁
    ​ Verilog UDP 基础知识分类
    一文带你了解怎样快速上手微信小程序开发
    JVM认识之垃圾收集算法
    分库分表知识点
  • 原文地址:https://blog.csdn.net/weixin_40763897/article/details/136083349