项目介绍
本项目的目标是实现一个C++程序,用于获取本机的IP地址和MAC地址。这些信息在网络调试、设备管理、局域网内通信等场景中非常常见。通过获取IP和MAC地址,可以用于设备识别、网络通信等应用。
什么是IP地址和MAC地址
-
IP地址:IP地址(Internet Protocol Address)是网络中设备的唯一标识,用于路由数据包。在IPv4中,IP地址是32位的,通常表示为四个数字(例如:192.168.1.1),而在IPv6中则是128位。
-
MAC地址:MAC地址(Media Access Control Address)是网络设备的物理地址,用于在局域网中唯一标识一个设备。MAC地址通常是48位的,表示为6个字节的十六进制数(例如:00:1A:2B:3C:4D:5E)。
项目实现思路
-
获取IP地址:
- 在Windows系统上,使用Windows API函数
GetAdaptersInfo
或GetAdapterAddresses
来获取IP地址。 - 在Linux系统上,可以通过
getifaddrs
函数获取网络接口的IP地址。
- 在Windows系统上,使用Windows API函数
-
获取MAC地址:
- 在Windows系统上,使用
GetAdaptersInfo
或GetAdapterAddresses
函数获取MAC地址。 - 在Linux系统上,通过读取
/sys/class/net/eth0/address
等文件获取MAC地址。
- 在Windows系统上,使用
-
输出信息:将获取到的IP和MAC地址输出到控制台。
项目代码
Windows系统
#include <iostream>
#include <windows.h>
#include <iphlpapi.h>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
// 函数:将字节数组转换为MAC地址字符串
string macToString(const BYTE* mac) {
stringstream macAddress;
for (int i = 0; i < 6; ++i) {
macAddress << setw(2) << setfill('0') << hex << (int)mac[i];
if (i != 5) macAddress << ":";
}
return macAddress.str();
}
// 函数:获取本机IP地址和MAC地址
void getNetworkInfo() {
// 获取适配器信息
IP_ADAPTER_INFO adapterInfo[16];
DWORD dwBufLen = sizeof(adapterInfo);
DWORD dwStatus = GetAdaptersInfo(adapterInfo, &dwBufLen);
if (dwStatus != ERROR_SUCCESS) {
cerr << "无法获取网络适配器信息" << endl;
return;
}
// 遍历所有适配器
PIP_ADAPTER_INFO adapter = adapterInfo;
while (adapter) {
cout << "适配器名称: " << adapter->AdapterName << endl;
cout << "IP地址: " << adapter->IpAddressList.IpAddress.String << endl;
cout << "MAC地址: " << macToString(adapter->Address) << endl;
cout << "---------------------------" << endl;
adapter = adapter->Next;
}
}
int main() {
// 获取网络信息
getNetworkInfo();
return 0;
}
Linux系统
#include <iostream>
#include <cstring>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <sstream>
#include <iomanip>
using namespace std;
// 函数:将字节数组转换为MAC地址字符串
string macToString(unsigned char* mac) {
stringstream macAddress;
for (int i = 0; i < 6; ++i) {
macAddress << setw(2) << setfill('0') << hex << (int)mac[i];
if (i != 5) macAddress << ":";
}
return macAddress.str();
}
// 函数:获取本机IP地址
string getLocalIP() {
struct ifaddrs *ifAddrStruct = nullptr;
struct ifaddrs *ifa = nullptr;
void *tmpAddrPtr = nullptr;
getifaddrs(&ifAddrStruct);
// 遍历所有网络接口
for (ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family == AF_INET) { // IPv4
// 获取IP地址
tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
char addressBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
return string(addressBuffer);
}
}
return "无法获取IP";
}
// 函数:获取本机MAC地址
string getMacAddress(const char* iface) {
struct ifreq ifr;
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
cerr << "无法打开套接字" << endl;
return "无法获取MAC地址";
}
// 获取MAC地址
strncpy(ifr.ifr_name, iface, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) == -1) {
cerr << "无法获取MAC地址" << endl;
close(sockfd);
return "无法获取MAC地址";
}
close(sockfd);
return macToString((unsigned char*)ifr.ifr_hwaddr.sa_data);
}
int main() {
// 获取本机IP地址
string ip = getLocalIP();
cout << "本机IP地址: " << ip << endl;
// 获取本机MAC地址
string mac = getMacAddress("eth0"); // 假设网络接口是"eth0"
cout << "本机MAC地址: " << mac << endl;
return 0;
}
代码解读
1. Windows系统实现
GetAdaptersInfo
:通过此API获取所有网络适配器的信息。每个适配器包含其IP地址和MAC地址。macToString
:将获取到的MAC地址(字节数组)转换为易于阅读的字符串格式。- 输出信息:通过遍历适配器信息,输出每个适配器的IP地址和MAC地址。
2. Linux系统实现
getLocalIP
:通过getifaddrs
函数遍历所有网络接口,找到第一个IPv4地址并返回。getMacAddress
:通过ioctl
函数获取指定接口(如eth0
)的MAC地址。macToString
:将MAC地址的字节数组转换为字符串格式。
项目总结
本项目展示了如何在Windows和Linux系统上使用C++获取本机的IP地址和MAC地址。通过不同的系统API和系统调用,程序能够成功地获取本机的网络信息,并将其输出。
进一步拓展
-
获取多个网络接口的信息:当前程序只获取一个网络接口的信息。如果机器有多个网络接口(如WiFi和Ethernet),可以扩展程序获取多个接口的IP和MAC地址。
-
跨平台支持:目前的实现分别适用于Windows和Linux。为了实现更好的跨平台支持,可以使用
#ifdef
预处理指令,根据不同的操作系统调用不同的API。 -
更详细的网络信息:除了IP和MAC地址,还可以获取更多的网络信息,如子网掩码、网关等。
通过本项目,读者可以了解如何使用C++在不同操作系统上获取本机的网络信息,了解不同平台下网络API的使用方式。