如何使用Windows API获取IP、MAC
来源:互联网 发布:经验模态分解 python 编辑:程序博客网 时间:2024/05/16 17:07
这里用的两个函数:gethostbyname/gethostbyaddr,GetAdaptersInfo,这里主要通过获取IP看链表的操作
获取所有IP地址的函数,如下:
int CIPInfo::GetIPInfo(const char * szHostName){#define HOST_NAME_MAX 256char szHost[HOST_NAME_MAX];HOSTENT* pHost;//LPSTR szIPAddr = NULL;char* szIPAddr = NULL;in_addr addr;memset(szHost, 0, ARRSIZE(szHost));if (szHostName){if (isalpha(szHostName[0])) /* host address is a name */{ #ifdef _DEBUGTRACE("Calling gethostbyname with %s\n", szHostName);#endif // _DEBUGpHost = gethostbyname(szHostName);} else if (isdigit(szHostName[0])) /* host address is a digit */{#ifdef _DEBUGTRACE("Calling gethostbyaddr with %s\n", szHostName);#endif // _DEBUGaddr.s_addr = inet_addr(szHostName);if (addr.s_addr == INADDR_NONE) {#ifdef _DEBUGTRACE("The IPv4 address entered must be a legal address\n");#endif // _DEBUGreturn -1;} else{pHost = gethostbyaddr((char *) &addr, 4, AF_INET);}}else{TRACE("The IPv4 address entered Error!\n");return -1;}}else{::gethostname(szHost, HOST_NAME_MAX);pHost = gethostbyname(szHost);}if (pHost->h_addrtype == AF_INET) {int i = 0;//char *p = NULL;while ( (szIPAddr = pHost->h_addr_list[i]) != 0) //Addresses are in network byte order{memcpy(&addr.s_addr, szIPAddr, pHost->h_length);szIPAddr = ::inet_ntoa(addr);#ifdef _DEBUGTRACE("\tIPv4 Address #%d: %s\n", i, szIPAddr);#endif // _DEBUGif (szIPAddr){PIPInfo ipInfo = GetIPObj(szIPAddr);if (ipInfo){InsertIPObj(*ipInfo);}}i++;}} else if (pHost->h_addrtype == AF_INET6){#ifdef _DEBUGTRACE("\tRemotehost is an IPv6 address\n");#endif // _DEBUGreturn -1;}return 0;}注意:
1)这里我将IP6排除在外了,只使用了IP4
2)还有一个就是这里面其实牵涉到Unicode和ANSI字符集I编码的问题,这里并没有严格遵守此规则
3)这里使用了ip地址和域名的方式,这里并没有涉及,因为此函数有个默认形参
在使用HOSTENT获得的结构中,包含本机ip地址的列表,就是h_addr_list,这里我将其保存在了如下的一个结构链表中
typedef struct IPInfo{charip[IP_ADDR_SIZE];IPInfo*next;}IPInfo, *PIPInfo;这里就需要牵涉堆内存空间的开辟和释放,链表的插入和删除,这里我是在类中写入的函数,所以我将释放放置于析构函数中,
如下内存空间的分配
PIPInfo CIPInfo:: GetIPObj(char* szIP){PIPInfo pIP = (PIPInfo)malloc(sizeof(IPInfo));if (pIP){memset(pIP->ip, 0, sizeof(pIP->ip));strcpy_s( pIP->ip, szIP);pIP->next = NULL;}return pIP;}先开辟空间,再填充数据,这里为了防止临时变量空间的释放,使用的是内容的复制
内存空间的释放:如下
int CIPInfo::FreeIPObj(PIPInfo pIPObj){if (pIPObj){free(pIPObj);pIPObj = NULL;}return 0;}释放空间后,一定要将指针置为NULL,至于为什么请参考:void * 与 空指针NULL
链表的插入:如下
int CIPInfo::InsertIPObj(IPInfo& pIPObj){PIPInfo pTest = m_ipAddrList;if (m_ipAddrList == NULL){m_ipAddrList = &pIPObj;}else{while ( pTest->next != NULL){pTest = pTest->next;}pTest->next = &pIPObj;}return 0;}这里m_ipAddrList是类的成员变量,这里链表没有头节点,也没有头指针或者尾指针,只有一个单向链表。链表为空,直接插入;链表不为空,插入尾部
链表的删除:如下:
int CIPInfo::RemoveIPObj(PIPInfo pIPObj){PIPInfo pTest = m_ipAddrList;if (pIPObj == NULL){return -1;}else if (pIPObj == pTest){m_ipAddrList = (pTest->next) ? pTest->next : NULL;}else{while ( (pTest->next != NULL) && (pTest->next != pIPObj) ){pTest = pTest->next;}if (pTest != NULL){pTest->next = (pIPObj->next) ? pIPObj->next : NULL;}}return 0;}这里要考虑链表为空的情况,通常移除的时候就会判断,这里只是保险起见,如果非空,要考虑删除的是否是头结点,是否是仅有一个结点,当时其他元素时,要考虑删除的是否是尾结点,以及在中间的结点。
MAC地址的获取不在阐述,如下:
int CIPInfo::GetMac(void){//PIP_ADAPTER_INFO pAdapterInfo = NULL;ULONG uLen = 0;/* 获得内存空间大小,然后申请内存空间*/if (GetAdaptersInfo(pAdapterInfo, &uLen) == ERROR_BUFFER_OVERFLOW) {pAdapterInfo = (PIP_ADAPTER_INFO)::GlobalAlloc(GPTR, uLen); //分配一块内容,并初始化为0if (pAdapterInfo == NULL) {TRACE("Error allocating memory needed to call GetAdaptersinfo\n");return -1;}}/* 取得适配器信息*/if ( ::GetAdaptersInfo(pAdapterInfo, &uLen) == ERROR_SUCCESS ){if (pAdapterInfo){memcpy(m_szLocalMac, pAdapterInfo->Address, MAC_ADDR_SIZE);strcpy_s(m_szLocalIP, pAdapterInfo->IpAddressList.IpAddress.String);strcpy_s(m_szMask, pAdapterInfo->IpAddressList.IpMask.String);strcpy_s(m_szGatewayIP, pAdapterInfo->GatewayList.IpAddress.String);}}return 0;}另外千万不要忘了内存空间的释放,因为不释放分配的空间,会导致内存泄露,如下析构函数
CIPInfo::~CIPInfo(void){PIPInfo pTest = m_ipAddrList;while (pTest){RemoveIPObj(pTest);FreeIPObj(pTest);pTest = m_ipAddrList->next;}m_ipAddrList = NULL;if (pAdapterInfo)GlobalFree(pAdapterInfo);}
测试用例:这里我使用了MFC的主窗口类,在一个编辑框中进行显示,如下测试代码:
void CSocketDlg::OnBnClickedOk(){// TODO: 在此添加控件通知处理程序代码CString strText = _T("");CString strTemp = _T("");CIPInfo ipInfo;int nIndex = -1;nIndex = m_comboBox.GetCurSel();m_comboBox.GetLBText(nIndex, strText);if (strText == _T("主机IP地址")){strText += _T("\r\n");PIPInfo IPInfoList;int nResult = -1;nResult = ipInfo.GetIPInfo();if( !nResult ){IPInfoList = ipInfo.GetIPList();while ( IPInfoList && (strTemp = (CString)IPInfoList->ip)){strTemp += _T("\r\n");strText += strTemp;IPInfoList = IPInfoList->next;}}}if (strText == _T("主机MAC地址")){strText += _T("\r\n");ipInfo.GetMac();strTemp.Format(_T("IP\t: %s\r\n"), (CString)ipInfo.GetLocalIP());strText += strTemp;strTemp.Format(_T("Mask\t: %s\r\n"), (CString)ipInfo.GetMask());strText += strTemp;strTemp.Format(_T("Gateway\t: %s\r\n"),(CString)ipInfo.GetGatewayIP());strText += strTemp;u_char* p = ipInfo.GetLocalMac();strTemp.Format(_T("MAC\t: %.2X-%.2X-%.2X-%.2X-%.2X-%.2X"),p[0],p[1],p[2],p[3],p[4],p[5]);strText += strTemp;}SetDlgItemText(IDC_SHOW_TEXT, strText);//CDialogEx::OnOK();}测试IP的结果如下:
主机IP地址
192.168.1.3
192.168.50.1
192.168.159.1
测试MAC配置信息的结果如下:
主机MAC地址
IP : 192.168.1.3
Mask : 255.255.255.0
Gateway : 192.168.1.1
MAC : 9C-4E-36-17-AA-A4
1 0
- 如何使用Windows API获取IP、MAC
- 使用windows API获取本地主机的MAC地址
- mac如何获取API的资源图片 和 Windows系统下如何查看API资源图片
- C#如何使用GetTcpTable API获取TCP/IP连接信息
- C#如何使用GetTcpTable API获取TCP/IP连接信息
- C#如何使用GetTcpTable API获取TCP/IP连接信息
- C#如何使用GetTcpTable API获取TCP/IP连接信息
- windows下如何获取系统音量(使用mixer api)
- 使用nginx等反向代理时获取Windows版客户端真实的ip及mac地址
- 使用百度api根据ip获取位置
- 使用IP Helper API获取本地IP地址表
- 用 Windows API “GetAdaptersInfo” 获取 MAC 时遇到的问题
- 用windows api获取mac地址和硬盘id编号
- 用windows api获取mac地址和硬盘id编号
- 用windows api获取mac地址和硬盘id编号
- 用 Windows API “GetAdaptersInfo” 获取 MAC 时遇到的问题
- 如何获取本机MAC地址 和 IP
- 获取MAC地址后如何快速解析IP地址
- Java--选择排序(SelectSort)
- 设计模式初探-工厂方法模式
- Java--冒泡排序(BubbleSort)
- the thinker of code complete -- Fundamental Data Types
- http 错误 404.3 not found win7 iis 设置
- 如何使用Windows API获取IP、MAC
- 最新Android SDK更新hosts 2013年12月更新
- 黑马程序员_关于多线程(写俄罗斯方块时遇到的)
- Windows 7 IIS (HTTP Error 500.21 - Internal Server Error)解决
- xml解析各种类库对比
- java中的BitSet学习
- Question
- 主库不停的情况下联机创建active dataguard
- 跟着《算法导论》学习——动态规划法(Dynamic programming)