windows下用c++獲取本機(jī)ip地址的三種方法
windows下用c++獲取本機(jī)ip地址
工作過程中遇到一個(gè)需求,需要獲取本機(jī)ip地址,同時(shí)獲取本機(jī)網(wǎng)絡(luò)連接情況,即網(wǎng)線是否連接。
經(jīng)過多番搜索,有如下3種方案。
1、管道+多進(jìn)程
思路:在一個(gè)cmd中執(zhí)行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
調(diào)用處代碼
CmdExc cmd("ipconfig"); cout<<cmd.getOutput().c_str()<<endl;
缺點(diǎn):
- 多進(jìn)程
- 會(huì)有cmd的黑框一閃而過
- 網(wǎng)線未插時(shí)無法獲取到ip配置
- 很坑爹的在MFC工程中沒法用,必須是控制臺(tái)的應(yīng)用。如win32工程,或者Qt工程下,都沒問題的。官方的解釋是窗口工程需要用CreateProcess來創(chuàng)建進(jìn)程實(shí)現(xiàn)功能。
優(yōu)點(diǎn):
- 可以知道是否插了網(wǎng)線。。。。因?yàn)闆]插就沒有顯示。。。
2、iphlpapi.lib
思路:使用iphlpapi庫
使用iphlpapi中的GetAdaptersInfo函數(shù)來獲取各個(gè)網(wǎng)卡的信息。
代碼如下:
代碼來自于官網(wǎng)msdn。個(gè)人稍加修改簡化。官方鏈接。
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; //第一次調(diào)用獲取需要開辟的內(nèi)存空間大小 if((ret=GetAdaptersInfo(pIpAdpInfo,&ulBufLen))==ERROR_BUFFER_OVERFLOW){ free(pIpAdpInfo); //分配實(shí)際所需要的內(nèi)存空間 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; }
缺點(diǎn):
- 稍微有些復(fù)雜
- 如果是vc6,默認(rèn)是不帶iphlpapi.lib這個(gè)庫的。。。。需要手動(dòng)安裝sdk。。。200來M。。。Qt5.2、vs2010均有這個(gè)庫。
優(yōu)點(diǎn):
- 可以知道網(wǎng)線連沒連,沒連,獲取到的是0.0.0.0。。。。
3、gethostbyname
思路:使用gethostbyname相關(guān)函數(shù)
代碼如下:
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; }
缺點(diǎn):
- 網(wǎng)線沒插時(shí)獲取到的ip是127.0.0.1。
- 獲取ip個(gè)數(shù)時(shí)不夠清晰,因?yàn)閔ostent結(jié)構(gòu)中h_addr_list是一個(gè)\0結(jié)尾的字符串,但是長度不是4的整數(shù)倍。。。。。因?yàn)樽詈蟾郊恿薶ostname字符串。。。。但是官網(wǎng)并未明說。。。我是從代碼中斷點(diǎn)看出來的。。。稍微有些坑
優(yōu)點(diǎn):
- 實(shí)現(xiàn)較簡單
詳細(xì)源代碼見我的gitee。
以上就是windows下用c++獲取本機(jī)ip地址的三種方法的詳細(xì)內(nèi)容,更多關(guān)于c++獲取本機(jī)ip地址的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語言實(shí)現(xiàn)單位車輛調(diào)度管理
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)單位車輛調(diào)度管理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C++中隱式類型轉(zhuǎn)換學(xué)習(xí)筆記
在本篇文章里小編給大家整理的是一篇關(guān)于C++中隱式類型轉(zhuǎn)換學(xué)習(xí)筆記內(nèi)容,有興趣的跟著小編來學(xué)習(xí)下吧。2020-02-02C++超詳細(xì)講解模擬實(shí)現(xiàn)vector
這篇文章主要介紹了C++ 容器 Vector 的使用方法,Vector 是一個(gè)能夠存放任意類型的動(dòng)態(tài)數(shù)組,有點(diǎn)類似數(shù)組,是一個(gè)連續(xù)地址空間,下文更多詳細(xì)內(nèi)容的介紹,需要的小伙伴可以參考一下2022-07-07