当前位置:首页 > 行业动态 > 正文

如何在C语言中获取网络适配器的详细信息?

摘要:通过命令可获取网络适配器信息,包括名称、状态、IP地址等,有助于了解网络连接情况。

在C语言中获取网络适配器信息,通常需要借助系统提供的API函数,以下是详细的介绍:

一、使用Windows API获取网络适配器信息

1、相关函数

GetAdaptersInfo:用于获取本地计算机的网络适配器信息,该函数会返回一个包含所有网络适配器信息的链表,每个节点是一个IP_ADAPTER_INFO结构体。

GlobalAllocHeapAlloc:用于为存储适配器信息的结构体分配内存。

2、示例代码

   include <Windows.h>
   include <IPHlpApi.h>
   include <stdio.h>
   pragma comment(lib, "IPHlpApi")
   pragma comment(lib, "ws2_32")
   int main() {
       PIP_ADAPTER_INFO pAdapterInfo = NULL;
       ULONG ulLen = sizeof(IP_ADAPTER_INFO);
       // 为适配器结构申请内存
       pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, ulLen);
       if (NULL == pAdapterInfo) {
           printf("Error allocating memory needed to call GetAdaptersInfo.
");
           return 1;
       }
       // 获取本地适配器结构信息
       if (ERROR_BUFFER_OVERFLOW == GetAdaptersInfo(pAdapterInfo, &ulLen)) {
           HeapFree(GetProcessHeap(), 0, pAdapterInfo);
           pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, ulLen);
           if (NULL == pAdapterInfo) {
               printf("Error allocating memory needed to call GetAdaptersInfo.
");
               return 1;
           }
       }
       if (ERROR_SUCCESS != GetAdaptersInfo(pAdapterInfo, &ulLen)) {
           printf("GetAdaptersInfo error!
");
           return 0;
       }
       SetConsoleTitle(TEXT("本地网卡适配器信息"));
       do {
           printf("ComboIndex:%d
", pAdapterInfo->ComboIndex);
           printf("Adapter Name:%s
", pAdapterInfo->AdapterName);
           printf("Adapter Desc:%s
", pAdapterInfo->Description);
           printf("Adapter Addr:");
           for (size_t i = 0; i < pAdapterInfo->AddressLength; i++) {
               if (i == (pAdapterInfo->AddressLength 1)) {
                   printf("%02X", (int)pAdapterInfo->Address[i]);
               } else {
                   printf("%02X-", (int)pAdapterInfo->Address[i]);
               }
           }
           printf("
");
           printf("Index:%d
", pAdapterInfo->Index);
           printf("Type:");
           switch (pAdapterInfo->Type) {
               case MIB_IF_TYPE_OTHER: printf("Other
"); break;
               case MIB_IF_TYPE_ETHERNET: printf("Ethernet
"); break;
               case MIB_IF_TYPE_TOKENRING: printf("Token Ring
"); break;
               case MIB_IF_TYPE_FDDI: printf("FDDI
"); break;
               case MIB_IF_TYPE_PPP: printf("PPP
"); break;
               case MIB_IF_TYPE_LOOPBACK: printf("Lookback
"); break;
               case MIB_IF_TYPE_SLIP: printf("Slip
"); break;
               default: printf("Unknow type %ld
", pAdapterInfo->Type); break;
           }
           printf("IP Address:%s
", pAdapterInfo->IpAddressList.IpAddress.String);
           printf("IP Mask:%s
", pAdapterInfo->IpAddressList.IpMask.String);
           printf("Gateway:%s
", pAdapterInfo->GatewayList.IpAddress.String);
           if (pAdapterInfo->DhcpEnabled) {
               printf("DHCP Enabled:Yes
");
               printf("DHCP Server:%s
", pAdapterInfo->DhcpServer.IpAddress.String);
           }
           pAdapterInfo = pAdapterInfo->Next;
       } while (pAdapterInfo != NULL);
       // 释放内存
       if (pAdapterInfo) {
           HeapFree(GetProcessHeap(), 0, pAdapterInfo);
       }
       return 0;
   }

二、使用Linux系统调用获取网络适配器信息

1、相关函数

ioctl:用于设备控制操作,通过它可以获取网络接口的信息,包括MAC地址等。

socket:创建套接字,用于与网络进行通信,在获取网络接口信息时,通常需要创建一个套接字来执行ioctl操作。

ifreq:用于存储网络接口的请求和响应数据结构。

2、示例代码

   include <stdio.h>
   include <stdlib.h>
   include <string.h>
   include <unistd.h>
   include <sys/ioctl.h>
   include <net/if.h>
   include <arpa/inet.h>
   int main() {
       int fd;
       struct ifreq ifr;
       char *iface = "eth0"; // 指定要获取信息的网络接口名称,quot;eth0"
       fd = socket(AF_INET, SOCK_DGRAM, 0);
       if (fd == -1) {
           perror("socket");
           exit(1);
       }
       strncpy(ifr.ifr_name, iface, IFNAMSIZ-1);
       if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
           perror("ioctl");
           close(fd);
           exit(1);
       }
       // 打印MAC地址
       unsigned char *mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;
       printf("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x
", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
       close(fd);
       return 0;
   }

三、常见问题及解答(FAQs)

1、问题:在Windows下使用GetAdaptersInfo函数时,如果返回ERROR_BUFFER_OVERFLOW错误怎么办?

解答:当GetAdaptersInfo函数返回ERROR_BUFFER_OVERFLOW错误时,说明最初分配的缓冲区大小不足以存储所有的适配器信息,此时需要根据函数返回的错误码重新分配足够大的缓冲区,然后再次调用GetAdaptersInfo函数获取完整的适配器信息。

2、问题:在Linux下使用ioctl函数获取网络接口信息时,如何指定要查询的网络接口?

解答:在使用ioctl函数获取网络接口信息时,可以通过设置ifreq结构体的ifr_name字段来指定要查询的网络接口名称,例如将ifr.ifr_name设置为"eth0"表示查询名为"eth0"的网络接口。

0