首页 > 编程语言 >C/C++ 实现枚举网上邻居信息

C/C++ 实现枚举网上邻居信息

时间:2023-12-05 15:58:19浏览次数:31  
标签:函数 句柄 指定 C++ 网上邻居 枚举 DWORD 资源

在Windows系统中,通过网络邻居可以方便地查看本地网络中的共享资源和计算机。通过使用Windows API中的一些网络相关函数,我们可以实现枚举网络邻居信息的功能,获取连接到本地网络的其他计算机的相关信息。本文将介绍一个简单的C++程序,使用Windows API枚举网络邻居信息,并获取对端名称、本机名称、主机名称以及主机IP等信息。

引言

首先,我们需要了解一下几个与网络邻居信息有关的Windows API函数:

NETRESOURCE 结构体是 Windows 网络 API 中的一个结构体,用于描述网络资源的信息。它在网络资源的枚举和连接等操作中经常被使用。

结构体定义

typedef struct _NETRESOURCE {
  DWORD         dwScope;
  DWORD         dwType;
  DWORD         dwDisplayType;
  DWORD         dwUsage;
  LPTSTR        lpLocalName;
  LPTSTR        lpRemoteName;
  LPTSTR        lpComment;
  LPTSTR        lpProvider;
} NETRESOURCE, *LPNETRESOURCE;

结构体成员

  • dwScope:指定资源的可见性。可能的取值为:
    • RESOURCE_CONNECTED:表示已连接的资源。
    • RESOURCE_CONTEXT:表示会话特定的资源。
  • dwType:指定资源的类型。可能的取值为:
    • RESOURCETYPE_ANY:表示任何类型的资源。
    • RESOURCETYPE_DISK:表示磁盘资源。
    • RESOURCETYPE_PRINT:表示打印机资源。
  • dwDisplayType:指定资源的显示类型。可能的取值为:
    • RESOURCEDISPLAYTYPE_GENERIC:表示通用资源。
    • RESOURCEDISPLAYTYPE_DOMAIN:表示域。
  • dwUsage:指定资源的使用类型。可能的取值为:
    • RESOURCEUSAGE_CONNECTABLE:表示资源可以连接。
    • RESOURCEUSAGE_CONTAINER:表示资源是一个容器,可以包含其他资源。
  • lpLocalName:指定本地驱动器或打印机的本地名称。
  • lpRemoteName:指定远程共享资源的网络名称。
  • lpComment:指定资源的注释。
  • lpProvider:指定提供资源的网络提供程序的名称。

WNetOpenEnum 是 Windows 网络功能中的一个API函数,WNetOpenEnum 通过指定的参数打开一个用于列举网络资源的枚举句柄。这个句柄可以在后续的操作中用于获取网络资源的枚举信息。

函数原型

DWORD WNetOpenEnum(
  DWORD         dwScope,
  DWORD         dwType,
  DWORD         dwUsage,
  LPNETRESOURCE lpNetResource,
  LPHANDLE      lphEnum
);

参数说明

  • dwScope:指定枚举的范围,可以是 RESOURCE_CONNECTEDRESOURCE_GLOBALNETRESOURCE_REMEMBEREDRESOURCE_CONTEXT 中的一个。
  • dwType:指定枚举资源的类型,可以是 RESOURCETYPE_DISKRESOURCETYPE_PRINTRESOURCETYPE_ANY 中的一个。
  • dwUsage:指定枚举资源的使用类型,可以是 RESOURCEUSAGE_CONNECTABLERESOURCEUSAGE_CONTAINERRESOURCEUSAGE_NOLOCALDEVICERESOURCEUSAGE_SIBLING 中的一个。
  • lpNetResource:指向 NETRESOURCE 结构的指针,用于指定枚举的起始位置。如果为 NULL,则从所有资源的最顶层开始枚举。
  • lphEnum:指向句柄的指针,用于接收枚举句柄。

返回值

如果函数调用成功,返回 NO_ERROR,否则返回一个错误代码,可以通过 GetLastError 函数获取详细信息。

WNetEnumResource 是 Windows 网络功能中的 API 函数之一,用于通过枚举句柄获取网络资源的详细信息,包括资源的类型、用途、本地名、远程名等信息。

函数原型

DWORD WNetEnumResource(
  HANDLE  hEnum,
  LPDWORD lpcCount,
  LPVOID  lpBuffer,
  LPDWORD lpBufferSize
);

参数说明

  • hEnum:枚举句柄,通过 WNetOpenEnum 函数获取的句柄。
  • lpcCount:指向一个变量的指针,该变量用于接收枚举的资源数目。
  • lpBuffer:指向一个缓冲区的指针,用于接收枚举的资源信息。
  • lpBufferSize:指向一个变量的指针,该变量用于指定或接收缓冲区的大小。

返回值

如果函数调用成功,返回 NO_ERROR,否则返回一个错误代码,可以通过 GetLastError 函数获取详细信息。

WNetCloseEnum 函数用于关闭由 WNetOpenEnum 函数打开的网络资源的枚举句柄。在使用 WNetOpenEnum 函数枚举网络资源后,当不再需要使用枚举句柄时,应该通过调用 WNetCloseEnum 函数来释放资源,避免内存泄漏。

函数定义

DWORD WNetCloseEnum(
  HANDLE hEnum
);

参数

  • hEnum:网络资源的枚举句柄,该句柄是由 WNetOpenEnum 函数返回的。

返回值

如果函数调用成功,返回 NO_ERROR,否则返回错误代码,可以通过 GetLastError 函数获取详细的错误信息。

代码实现

以下是一个简单的C++程序,使用上述API函数实现了枚举网络邻居信息的功能。该程序通过遍历枚举得到的网络资源信息,获取对端名称、本机名称、主机名称以及主机IP等信息,并输出到控制台。

#include <iostream>
#include <Windows.h>
#include <winnetwk.h>

#pragma comment(lib,"Mpr.lib")
#pragma comment(lib,"Ws2_32.lib")

// 枚举网络邻居
BOOL EnumNetResource()
{
  NETRESOURCE  *NetResource = NULL;
  HANDLE  hEnum;
  unsigned  int  i;
  char szHostName[MAX_PATH] = { 0 };
  hostent *host = NULL;
  char *lpszIP = NULL;

  // 通过WSAStartup函数完成对Winsock服务的初始化
  WSADATA wsaData = { 0 };
  WSAStartup(MAKEWORD(2, 2), &wsaData);

  // 指定枚举范围, 获取枚举句柄
  WNetOpenEnum(RESOURCE_CONTEXT, NULL, NULL, NULL, &hEnum);
  if (hEnum)
  {
    DWORD  Count = 0xFFFFFFFF;
    DWORD  BufferSize = 2048;
    BYTE *pBuffer = new  BYTE[2048];

    // 根据设置的枚举返回, 获取枚举信息
    WNetEnumResource(hEnum, &Count, pBuffer, &BufferSize);
    NetResource = (NETRESOURCE*)pBuffer;

    for (i = 0; i < BufferSize / sizeof(NETRESOURCE); i++, NetResource++)
    {
      // 判断资源类型是否是所有资源 以及 判断资源使用类型是否是容器资源
      if (NetResource->dwUsage == RESOURCEUSAGE_CONTAINER  && NetResource->dwType == RESOURCETYPE_ANY)
      {
        if (NetResource->lpRemoteName)
        {
          // 获取远程主机名
          RtlZeroMemory(szHostName, MAX_PATH);
          lstrcpy(szHostName, (char *)((DWORD64)NetResource->lpRemoteName + 2));

          // 根据主机名获取IP地址信息
          host = gethostbyname(szHostName);
          if (host == NULL)
          {
            std::cout << "错误代码" << std::endl;
            continue;
          }

          // 将Ipv4网络地址转换为Internet标准点分十进制格式的ASCII字符串
          lpszIP = inet_ntoa(*(in_addr *)host->h_addr_list[0]);
          std::cout << "对端名称: " << NetResource->lpRemoteName
            << " 本机名称: " << NetResource->lpLocalName
            << " 主机名称: " << szHostName
            << " 主机IP: " << lpszIP
            << std::endl;
        }
      }
    }

    // 释放内存并关闭句柄
    delete[]pBuffer;
    pBuffer = NULL;
    WNetCloseEnum(hEnum);
  }
  return TRUE;
}

int main(int argc, char *argv[])
{
  EnumNetResource();

  system("pause");
  return 0;
}

结语

通过这个简单的程序,我们可以了解如何使用Windows API函数来枚举网络邻居信息。这对于需要在程序中获取网络中其他计算机信息的场景是非常有用的。在实际应用中,可以根据需要进一步扩展和优化代码,以满足特定的功能需求。

标签:函数,句柄,指定,C++,网上邻居,枚举,DWORD,资源
From: https://www.cnblogs.com/LyShark/p/17877440.html

相关文章

  • c++回调函数
    最近用到了回调函数,距离上次使用至少隔了5年了,又重新熟悉了一下。  转自:https://blog.csdn.net/hua12134/article/details/88264250什么是函数指针函数指针就是指向函数的指针,指向某种特定的类型。函数的类型由它的返回类型和形参类型共同决定,与函数名无关,例如:boollength......
  • c++传参时 值传递和引用传递的区别
    值传递需要开辟存储空间并拷贝这个对象,引用传递只是给这个对象起了一个别名,不涉及开辟空间和拷贝操作,引用传递更高效值传递在调用函数中修改的不是原来的对象,而引用传递在调用函数中就能直接修改原来的对象举个例子体会一下:435.无重叠区间贪心算法求解,涉及到排序操作,排序函数......
  • C/C++ 原生套接字抓取FTP数据包
    网络通信在今天的信息时代中扮演着至关重要的角色,而对网络数据包进行捕获与分析则是网络管理、网络安全等领域中不可或缺的一项技术。本文将深入介绍基于原始套接字的网络数据包捕获与分析工具,通过实时监控网络流量,实现抓取流量包内的FTP通信数据,并深入了解数据传输的细节,捕捉潜在......
  • C++:如何将 LLVM 嵌套到你的项目中去
    IDE:ClionLLVMcmake_minimum_required(VERSION3.9)project(clang_demo)find_package(LLVMREQUIREDCONFIG)message(STATUS"FoundLLVM${LLVM_PACKAGE_VERSION}")message(STATUS"UsingLLVMConfig.cmakein:${LLVM_DIR}")......
  • C++_线程池代码看C++类-模板-标准库
    C++线程池线程池的组成部分:线程池管理器(ThreadPoolManager):用于创建并管理线程池工作线程(WorkThread):线程池中线程任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行。任务队列:用于存放没有处理的任务。提供一种缓冲机制。 通过新......
  • 一. C++基础
    文章参考:《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)_白鳯的博客-CSDN博客1.一个简单的案例#include<iostream>//编译预处理命令usingnamespacestd;//使用命名空间intadd(inta,intb);//函数原型说明intmain()//主函数{ intx,y;......
  • 2021 最佳 C++ IDE 排行
    2021最佳C++IDE排行 BlogAuthor:DoriExtermanPublishedOn:5月31,2021Estimatedreadingtime:1minutes想把所有优秀的 IDE(集成开发环境)或类似 IDE 的工具在一篇文章内梳理出来,比登天还难。不过,JetBrains的调查数据显示,75% 的受访者经常使用 IDE。这些工具推......
  • 最佳 C++ 编译器
    最佳C++编译器Incredibuild​已认证账号​关注 134人赞同了该文章 C++是一个“开放”的编程语言,任何人都可以使用自己喜欢的编译器。当然,C++编译器的种类也很多。同样, C++IDE 也不少,我在之前的一个博客中讨论过这个话题。编译和运行C++......
  • C++ 内联函数 inline
    宏定义实现和普通函数实现:-宏定义是直接在实现的时候进行代码替换,可能产生结果异常问题。-普通函数实现:调用函数进出函数体的时候时间开销可能过大。1#include<iostream>2usingnamespacestd;3//宏实现4#defineGETMAX(a,b)((a)>(b)?(a):(b))......
  • c++ friend关键字 友元
     在C++中,friend关键字用于声明友元函数或友元类1。友元函数或友元类可以访问当前类的私有成员和保护成员,即使它们不是当前类的成员函数或成员类1。友元函数是一个独立的函数,而友元类是一个类可以访问另一个类的私有成员和保护成员1。例如,如果要声明函数为一个类的友元,需要......