关于

本文样式环境: win10 + vs2017 + c++11

1.说明

算是踩坑吧,先前一直认为一块网卡只能有一个IP。 今天发现结构体中,定义了相关结构: 一块网卡可以用多个IP

2.连接库和头文件

  • 2.1 头文件
#include <WinSock2.h>
#include <Iphlpapi.h>
  • 2.2 库
Iphlpapi.lib

3.封装类

自己做了个封装,以后用,直接就它了。

  • 3.1 头文件 源码
#pragma once
#include <string>
#include <list> #if defined(_WIN32) || defined(_WIN64)
#ifndef os_is_win
#define os_is_win
#endif // !os_is_win #elif defined(__linux__) || defined(_linux_) || defined(__unix) || defined(_unix_) || defined(_APPLE_)
#ifndef os_is_linux
#define os_is_linux
#endif // !os_is_linux #endif// ! defined(_WIN32) || defined(_WIN64) #if defined(os_is_win) #ifndef _net_api_export_
#define _net_api_export_ __declspec(dllexport)
#else
#define _net_api_export_ __declspec(dllimport)
#endif // !#ifndef _net_api_export_ #elif defined(os_is_linux) #ifndef _net_api_export_
#define _net_api_export_ __attribute__((visibility ("default")))
#endif // !_net_api_export_ #endif //! defined(os_is_win) namespace lib_net
{ /**
* @brief: ip information
*/
struct ip_info_
{
std::string _inet4;
std::string _inet6;
std::string _subnet_mask;
std::string _gate; void zero()
{
_inet4 = { "" };
_inet6 = { "" };
_subnet_mask = { "" };
_gate = { "" };
} ip_info_()
{
zero();
}
}; using ip_info = ip_info_;
using ip_list = std::list< ip_info>; /**
* @brief: the information of adapter
*/
struct net_adapter_info_
{
#ifdef os_is_win
int _index;
#endif //! os_is_win std::string _name;
std::string _description;
std::string _dev_type;
std::string _mac; ip_list _ip;
int _ip_size; void zero()
{
#ifdef os_is_win
_index = 0;
#endif //! os_is_win
_name = { "" };
_description = { "" };
_dev_type = { "" };
_mac = { "" };
_ip.clear();
_ip_size = 0;
} net_adapter_info_()
{
zero();
}
}; // to rename the type
using net_ada_info = net_adapter_info_; // maybe, this machine has greater than 1 adapter
using net_ada_list = std::list<net_ada_info>; //---------------------------------------------------------------------------------------- /**
* @brief: you could get the adapter information through this class on windows, linux and osx
*/
class _net_api_export_ net_adapter_helper
{
public:
//---------------------------------------------------------------------------------------- static net_adapter_helper& get_instance(); /**
* @brief: 获取Windows网卡信息
*/
net_ada_list get_info_win(); private:
template<typename ... Args>
static std::string str_format(const std::string &format, Args ... args)
{
auto size_buf = std::snprintf(nullptr, 0, format.c_str(), args ...) + 1;
std::unique_ptr<char[]> buf(new(std::nothrow) char[size_buf]); if (!buf)
return std::string(""); std::snprintf(buf.get(), size_buf, format.c_str(), args ...); return std::string(buf.get(), buf.get() + size_buf - 1);
} //----------------------------------------------------------------------------------------
net_adapter_helper() = default;
virtual ~net_adapter_helper() = default; net_adapter_helper(const net_adapter_helper& instance) = delete;
net_adapter_helper& operator = (const net_adapter_helper& instance) = delete;
net_adapter_helper(const net_adapter_helper&& instance) = delete;
net_adapter_helper& operator = (const net_adapter_helper&& instance) = delete; };
}
  • 3.2 源文件源码
#include "ip_helper.h"

#include <memory>
#include <string> #if defined(os_is_win)
#include <WinSock2.h>
#include <Iphlpapi.h>
#endif //! defined(os_is_win) namespace lib_net
{ /**
* @brief:
*/
lib_net::net_adapter_helper& net_adapter_helper::get_instance()
{
static net_adapter_helper instance; return instance;
} /**
* @brief:
*/
lib_net::net_ada_list net_adapter_helper::get_info_win()
{
net_ada_list ret_list; std::unique_ptr< IP_ADAPTER_INFO> pai(new(std::nothrow) IP_ADAPTER_INFO); // 1. failed to apply space
if (nullptr == pai || NULL == pai)
return ret_list; // 2. to get the size of IP_ADAPTER_INFO structure
unsigned long iai_size = sizeof(IP_ADAPTER_INFO); // 3.调用GetAdaptersInfo函数, 填充pIpAdapterInfo指针变量; 其中stSize参数既是一个输入量也是一个输出量
int ret_val = GetAdaptersInfo(pai.get(), &iai_size); if (ERROR_BUFFER_OVERFLOW == ret_val)
{
pai.release(); //重新申请内存空间用来存储所有网卡信息
pai.reset((IP_ADAPTER_INFO*)(new(std::nothrow) char[iai_size])); if (nullptr == pai || NULL == pai)
{
return ret_list;
} //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量
ret_val = GetAdaptersInfo(pai.get(), &iai_size);
} if (ERROR_SUCCESS == ret_val)
{
// 3. to get information
net_ada_info item;
IP_ADAPTER_INFO *ppai = pai.get(); while (ppai)
{
item._index = ppai->Index;
item._name = std::string(ppai->AdapterName);
item._description = std::string(ppai->Description); // dev
std::string str_type;
switch (ppai->Type)
{
case MIB_IF_TYPE_OTHER:
str_type = {"OTHER"};
break; case MIB_IF_TYPE_ETHERNET:
str_type = { "ETHERNET" };
break; case MIB_IF_TYPE_TOKENRING:
str_type = { "TOKENRING" };
break; case MIB_IF_TYPE_FDDI:
str_type = { "FDDI" };
break; case MIB_IF_TYPE_PPP:
str_type = { "PPP" };
break; case MIB_IF_TYPE_LOOPBACK:
str_type = { "LOOPBACK" };
break; case MIB_IF_TYPE_SLIP:
str_type = { "SLP" };
break; default:
str_type = { "" };
break;
} item._dev_type = str_type; // mac
std::string str_mac;
for (DWORD i = 0; i < ppai->AddressLength; i++)
{
if (i < ppai->AddressLength - 1)
str_mac += str_format("%02X-", ppai->Address[i]);
else
str_mac += str_format("%02X", ppai->Address[i]);
} item._mac = str_mac; // ip information
ip_info ii_item;
IP_ADDR_STRING *pial = &(ppai->IpAddressList);
int ip_size = 0;
for (;;)
{
if (NULL != pial && nullptr != pial)
{
ii_item._inet4 = std::string(pial->IpAddress.String);
ii_item._subnet_mask = std::string(pial->IpMask.String);
ii_item._gate = std::string(pai->GatewayList.IpAddress.String); item._ip.push_back(ii_item);
pial = pial->Next;
ii_item.zero();
ip_size++;
}
else
{
break;
}
} item._ip_size = ip_size;
ret_list.push_back(item);
item.zero(); ppai = ppai->Next;
} // end while
}
else
{
;// error
} return ret_list;
} }

4.使用

net_ada_list nal = net_adapter_helper::get_instance().get_info_win();
int list_size = nal.size(); cout << "1.适配器数目 = " << list_size << "\n\n" << endl; #if defined(os_is_win)
for (auto item : nal)
{
cout << "索引=" << item._index << endl;
cout << "名字=" << item._name.c_str() << endl;
cout << "描述=" << item._description.c_str() << endl;
cout << "类型=" << item._dev_type.c_str() << endl;
cout << "MAC=" << item._mac.c_str() << endl; int index = 0;
cout << "ip有=" << item._ip_size << "个" << endl;
for (auto item_ip : item._ip)
{
cout << "第" << ++index << "个ip" << endl;
cout << "ipv4 = " << item_ip._inet4.c_str() << endl;
cout << "子网掩码 = " << item_ip._subnet_mask.c_str() << endl;
cout << "网关 = " << item_ip._gate.c_str() << endl;
cout << "\n-------------------------";
} cout << "\n--------------------------------------------------\n\n";
} #endif //

Windows10 c++获取网卡信息(ipv4,子网掩码,网关,mac地址)的更多相关文章

  1. ARP防火墙绑定网关MAC地址预防ARP攻击和P2P终结者

    [故障原理]  要了解故障原理,我们先来了解一下ARP协议.  在局域网中,通过ARP协议来完成IP地址转换为第二层物理地址(即MAC地址)的.ARP协议对网络安全具有重要的意义.通过伪造IP地址和M ...

  2. arp绑定网关MAC地址错误

    为了防止局域网的arp 要绑定网关MAC地址 在vista/win中 用 arp -s 绑定网关会出现错误 ARP 项添加失败 C:\Users\sink>arp -a 接口: 10.200.5 ...

  3. 获取本机IP、mac地址、计算机名

    python获取本机IP.mac地址.计算机名 在python中获取ip地址和在php中有很大不同,我们先来看一下python 获得本机MAC地址: >>> import uuid ...

  4. 获取Android设备WIFI的MAC地址 “MAC地址”

    需要指出的是:wifi状态和wifi AP状态是互斥的状态:也就是一旦发现WIFI AP打开,WIFI是不能被打开的. 获取Android设备的WIFI MAC地址,首先需要将设备中的WIFI个人热点 ...

  5. c#中如何获取本机用户名、MAC地址、IP地址、硬盘ID、CPU序列号、系统名称、物理内存

    我们在利用C#开发桌面程序(Winform)程序的时候, 经常需要获取一些跟系统相关的信息, 以下这些代码获取能有些用处. c#中如何获取本机用户名.MAC地址.IP地址.硬盘ID.CPU序列号.系统 ...

  6. IP、CIDR、广播地址、子网掩码、MAC地址--这些是什么鬼

    继续学习趣谈网络协议中的内容,认识几个专有名词,IP.CIDR.广播地址.子网掩码.MAC地址,这些都是什么鬼? 一.IP IP地址是一个网卡在网络世界的通讯地址,相当于我们现实世界的门牌号码 (1) ...

  7. Linux 获取本机IP、MAC地址用法大全

    getifaddrs()和struct ifaddrs的使用,获取本机IP ifaddrs结构体定义如下: struct ifaddrs { struct ifaddrs *ifa_next; /* ...

  8. QT获取本机IP和Mac地址

    #include <QNetworkInterface> #include <QList> void MainWindow::getIPPath() { QString str ...

  9. python获取本机IP、mac地址、计算机名

    在python中获取ip地址和在php中有很大不同,在php中往往比较简单.那再python中怎么做呢? 我们先来看一下python 获得本机MAC地址: 1 2 3 4 import uuid de ...

  10. JAVA获取本机IP和Mac地址

       在项目中,时常需要获取本机的Ip或是Mac地址,进行身份和权限验证,本文就是通过java代码获取ip和Mac. package com.svse.query;import java.net.In ...

随机推荐

  1. GWAS数据分析常见的202个问题?

    生信其实很简单,就是用别人的工具调参就行了.生信也很折腾,哪一步都可能遇到问题,随时让你疯掉(老辩证法了~).但是,你遇到的问题大部分人也都经历过.这时,检索技能就显得很重要了.平时Biostar和S ...

  2. linux 线程函数小结

    由于主线程已经开始跑了,次线程还在使用串口打印需要一点时间,因此打印的都是重复的. #include "pthread.h" #include "stdio.h" ...

  3. 基于 Helm 快速部署 Wordpress

    Helm 是 Kubernetes 中的一个开源软件包管理工具,Rainbond 从 5.3.1 版本开始支持部署 Helm 应用.实现 Helm 应用的便捷部署,访问控制.使 Rainbond 用户 ...

  4. 第一个基础框架 — mybatis框架 — 更新完毕

    1.Mybatis是什么? 百度百科一手 提取一下重点: MyBatis 本是apache的一个开源项目iBatis.即:mybatis的原名为:ibatis 2010年迁移到google code, ...

  5. 学习java的第二十三天

    一.今日收获 1.java完全学习手册第三章算法的3.2排序,比较了跟c语言排序上的不同 2.观看哔哩哔哩上的教学视频 二.今日问题 1.快速排序法的运行调试多次 2.哔哩哔哩教学视频的一些术语不太理 ...

  6. keeper及er表示被动

    一些像employ这样的动词有employer和employee两个名词,而keep的名词只有keeper,keepee不是词.美剧FRIENDS和TBBT里出现了He/she is a keeper ...

  7. Hbase(一)【入门安装及高可用】

    目录 一.Zookeeper正常部署 二.Hadoop正常部署 三.Hbase部署 1.下载 2.解压 3.相关配置 4.分发文件 5.启动.关闭 6.验证 四.HMaster的高可用 一.Zooke ...

  8. Kafka(一)【概述、入门、架构原理】

    目录 一.Kafka概述 1.1 定义 二.Kafka快速入门 2.1 安装部署 2.2 配置文件解析 2.3Kafka群起脚本 2.4 topic(增删改查) 2.5 生产和消费者命令行操作 三.K ...

  9. CPU 是如何认识和执行代码的

    CPU的介绍 CPU 也称为微处理器,是计算机的心脏和/或大脑. 深入研究计算机的核心,可以帮助我们有效地编写计算机程序. CPU 是计算机的心脏和大脑,它执行提供给他们的指令.它的主要工作是执行算术 ...

  10. NuxtJS的AsyncData和Fetch使用详解

    asyncData 简介 asyncData 可以用来在客户端加载 Data 数据之前对其做一些处理,也可以在此发起异步请求,提前设置数据,这样在客户端加载页面的时候,就会直接加载提前渲染好并带有数据 ...