关于

本文样式环境: 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. R语言与医学统计图形-【17】ggplot2几何对象之热图

    ggplot2绘图系统--heatmap.geom_rect 这里不介绍更常见的pheatmap包. 1.heatmap函数 基础包. data=as.matrix(mtcars) #接受矩阵 hea ...

  2. PPT——一个有情怀的免费PPT模板下载网站!“优品PPT”

    http://www.ypppt.com/ PS:再推荐一款免费PPT下载网站 https://www.v5ppt.com/ppt-5-42-1.html

  3. Vue3 中有哪些值得深究的知识点?

    众所周知,前端技术一直更新很快,这不 vue3 也问世这么久了,今天就来给大家分享下vue3中值得注意的知识点.喜欢的话建议收藏,点个关注! 1.createApp vue2 和 vue3 在创建实例 ...

  4. 学习java 7.21

    学习内容: 模块使用 AWT是窗口框架 它从不同平台的窗口系统中抽取出共同组件,当程序运行时,将这些组件的创建和动作委托给程序所在的运行平台.简而言之,当使用AWT编写图形界面应用时,程序仅指定了界面 ...

  5. 虚拟机中安装centos系统的详细过程

    linux-centos的安装 检查电脑是否开启虚拟化,只有开启虚拟化才能安装虚拟机 新建虚拟机 鼠标点进去,选中红框所示,回车 登录: 输入默认用户名(超级管理员 root) 密码:安装时设置的密码

  6. 单体内置对象 Global 和 Math

    单体内置对象 Global 和 Math 在所有代码执行前,作用域中就已经存在两个内置对象:Global(全局)和Math.在大多数ES实现中都不能直接访问Global对象.不过,WEB浏览器实现了承 ...

  7. CRLF漏洞浅析

    部分情况下,由于与客户端存在交互,会形成下面的情况 也就是重定向且Location字段可控 如果这个时候,可以向Location字段传点qqgg的东西 形成固定会话 但服务端应该不会存储,因为后端貌似 ...

  8. git pull、git fetch、git merge、git rebase的区别

    一.git pull与git fetch区别 1.两者的区别       两者都是更新远程仓库代码到本地. git fetch相当于是从远程获取最新版本到本地,不会自动merge. 只是将远程仓库最新 ...

  9. 深入理解java动态代理机制

    动态代理其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组 ...

  10. android:为TextView添加样式、跑马灯、TextSwitcher和ImageSwitcher实现平滑过渡

    一.样式 设置下划线: textView.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);//下划线 textView.getPaint().setAnt ...