windows下用c++获取本机ip地址的三种方法

 更新时间:2023年11月19日 10:15:31   作者:WarmSword  
工作过程中遇到一个需求,需要获取本机ip地址,同时获取本机网络连接情况,即网线是否连接,经过多番搜索,本文给大家介绍了3种方案,通过代码示例介绍的非常详细,需要的朋友可以参考下

windows下用c++获取本机ip地址

工作过程中遇到一个需求,需要获取本机ip地址,同时获取本机网络连接情况,即网线是否连接。

经过多番搜索,有如下3种方案。

1、管道+多进程

思路:在一个cmd中执行ipconfig并获取其输出。

代码如下:

#ifndef CMDEXC_H
#define CMDEXC_H

#include <string>


class CmdExc
{
public:
    CmdExc(std::string cmd,std::string mode="rt");
    virtual ~CmdExc();

    std::string getOutput() const;

private:
    std::string m_strOutput__;
    FILE* m_fp__;
};



CmdExc::CmdExc(std::string cmd, std::string mode)
{
    m_fp__=_popen(cmd.c_str(),mode.c_str());
    char buf[256]={0};
    if(NULL != m_fp__){
        int read_len;
        while((read_len=fread(buf,sizeof(buf)-1,1,m_fp__))>0){
            m_strOutput__+=buf;
            memset(buf,0,sizeof(buf));
        }
    }

}

CmdExc::~CmdExc()
{
    if(NULL != m_fp__){
        _pclose(m_fp__);
    }
}

std::string CmdExc::getOutput() const
{
    return m_strOutput__;
}

#endif // CMDEXC_H

调用处代码

CmdExc cmd("ipconfig");
cout<<cmd.getOutput().c_str()<<endl;

缺点:

  • 多进程
  • 会有cmd的黑框一闪而过
  • 网线未插时无法获取到ip配置
  • 很坑爹的在MFC工程中没法用,必须是控制台的应用。如win32工程,或者Qt工程下,都没问题的。官方的解释是窗口工程需要用CreateProcess来创建进程实现功能。

优点:

  • 可以知道是否插了网线。。。。因为没插就没有显示。。。

2、iphlpapi.lib

思路:使用iphlpapi库

使用iphlpapi中的GetAdaptersInfo函数来获取各个网卡的信息。

代码如下:

代码来自于官网msdn。个人稍加修改简化。官方链接

std::vector<string> IpDealer::getAdptInfo() {
    vector<string> result;
    IP_ADAPTER_INFO *pAdpFree=NULL;
    IP_ADAPTER_INFO *pIpAdpInfo=(IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
    unsigned long ulBufLen=sizeof(IP_ADAPTER_INFO);
    int ret;
    //第一次调用获取需要开辟的内存空间大小
    if((ret=GetAdaptersInfo(pIpAdpInfo,&ulBufLen))==ERROR_BUFFER_OVERFLOW){
        free(pIpAdpInfo);
        //分配实际所需要的内存空间
        pIpAdpInfo=(IP_ADAPTER_INFO*)malloc(ulBufLen);
        if(NULL == pIpAdpInfo){
            return result;
        }
    }

    char ip[256];
    if((ret=GetAdaptersInfo(pIpAdpInfo,&ulBufLen))==NO_ERROR){
        pAdpFree=pIpAdpInfo;

        for(int i=0;pIpAdpInfo;i++){
            string addr;
            snprintf(ip,sizeof(ip),"netcard%d ip addr:",i);
            addr+=ip;
            IP_ADDR_STRING *pIps=&pIpAdpInfo->IpAddressList;
            while(pIps){
                snprintf(ip,sizeof(ip),"ip:%s,mask:%s,gate:%s.",pIps->IpAddress.String,
                         pIps->IpMask.String,pIpAdpInfo->GatewayList.IpAddress.String);
                addr+=ip;
                cout<<pIps->IpAddress.String<<endl;
                cout<<pIps->IpMask.String<<endl;
                cout<<pIpAdpInfo->GatewayList.IpAddress.String<<endl;
                pIps=pIps->Next;
            }
            result.push_back(addr);
            pIpAdpInfo=pIpAdpInfo->Next;
        }
    }
    if(pAdpFree){
        free(pAdpFree);
    }
    return result;

}

缺点:

  • 稍微有些复杂
  • 如果是vc6,默认是不带iphlpapi.lib这个库的。。。。需要手动安装sdk。。。200来M。。。Qt5.2、vs2010均有这个库。

优点:

  • 可以知道网线连没连,没连,获取到的是0.0.0.0。。。。

3、gethostbyname

思路:使用gethostbyname相关函数

代码如下:

std::vector<std::string> IpDealer::getIpList()
{
    std::vector<std::string> result;
    char name[256];

    int getNameRet=gethostname(name,sizeof(name));

    hostent *host=gethostbyname(name);

    if(NULL == host){
        return result;
    }

    in_addr *pAddr=(in_addr*)*host->h_addr_list;

    for(int i=0;i<(strlen((char*)*host->h_addr_list)-strlen(host->h_name) )/4 && pAddr;i++){
        string addr=inet_ntoa(pAddr[i]);
        cout<<addr.c_str()<<endl;
        result.push_back(addr);
    }

    return result;
}

缺点:

  • 网线没插时获取到的ip是127.0.0.1。
  • 获取ip个数时不够清晰,因为hostent结构中h_addr_list是一个\0结尾的字符串,但是长度不是4的整数倍。。。。。因为最后附加了hostname字符串。。。。但是官网并未明说。。。我是从代码中断点看出来的。。。稍微有些坑

优点:

  • 实现较简单

详细源代码见我的gitee

以上就是windows下用c++获取本机ip地址的三种方法的详细内容,更多关于c++获取本机ip地址的资料请关注脚本之家其它相关文章!

相关文章

  • c++ 移动构造相关总结

    c++ 移动构造相关总结

    这篇文章主要介绍了c++ 移动构造的相关资料,帮助大家更好的理解和学习使用c++,感兴趣的朋友可以了解下
    2021-02-02
  • 一起来看看C语言线性表的线性链表

    一起来看看C语言线性表的线性链表

    这篇文章主要为大家详细介绍了C语言线性表的线性链表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • 基于Qt实现可拖动自定义控件

    基于Qt实现可拖动自定义控件

    这篇文章主要为大家详细介绍了如何基于Qt实现可拖动自定义控件,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以了解一下
    2023-04-04
  • C语言如何利用ASCII码表统计字符串每个字符出现的次数

    C语言如何利用ASCII码表统计字符串每个字符出现的次数

    这篇文章主要介绍了C语言如何利用ASCII码表统计字符串每个字符出现的次数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • C/C++实现目录监视器的方法详解

    C/C++实现目录监视器的方法详解

    这篇文章主要介绍了C/C++ 实现目录监视器的方法,然后网上查到的基本就有三种方法,使用FindFirstChangeNotification等系列函数,使用ReadDirectoryChangesW函数和使用change journals,本文使用了第二种方式来实现一个目录监视,需要的朋友可以参考下
    2024-04-04
  • C/C++中宏/Macro的深入讲解

    C/C++中宏/Macro的深入讲解

    这篇文章主要给大家介绍了关于C/C++中宏/Macro的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C/C++具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • C语言文件操作详情(一)

    C语言文件操作详情(一)

    这篇文章主要介绍了C语言文件操作详情,主要讨论的是数据文件,通过处理的磁盘上的文件展开主题内容介绍,需要的小伙伴可以参考一下,希望对你的学习有所帮助
    2022-04-04
  • Qt数据库应用之实现通用数据库采集

    Qt数据库应用之实现通用数据库采集

    这篇文章主要为大家介绍了Qt中是如何实现通用数据库采集的,文中的示例代码讲解详细,对我们学习Qt有一定帮助,感兴趣的小伙伴可以了解一下
    2022-03-03
  • 基于linux下C开发中的几点技术经验总结

    基于linux下C开发中的几点技术经验总结

    本篇文章是对linux下C开发中的几点技术经验总结进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • Qt可视化大屏布局的实现

    Qt可视化大屏布局的实现

    数据可视化大屏在项目中的使用很常见,本文主要介绍了Qt可视化大屏布局的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02

最新评论