☰
DHCP 故障转移关系枚举实战:DhcpV4FailoverEnumRelationship API 使用指南(Windows-classic-samples)
2026/10/15 1:53:05 网站建设 项目流程
  • 示例工程

【免费下载链接】Windows-classic-samples

This repo contains samples that demonstrate the API used in Windows classic desktop applications.

项目地址:https://gitcode.com/gh_mirrors/wi/Windows-classic-samples
点击查看免费下载

导读

本文以 Windows-classic-samples 仓库中的 EnumRelationship 示例 为主线,系统讲解 Windows DHCP Server 管理 API 中DhcpV4FailoverEnumRelationship的完整用法:包括分页枚举的调用模式、返回值语义、结果数据的读取与内存释放,以及它在 DHCP 故障转移(Failover)管理 API 家族中的定位。读完本文,你将掌握如何用 C++ 遍历一台 DHCP 服务器上的全部故障转移关系,并能在此基础上扩展到创建、查询、修改、删除关系的配套 API。

一、示例背景:DHCP 与故障转移关系

DHCP(Dynamic Host Configuration Protocol)是一种标准化协议,允许客户端被动态分配 IP 地址、子网掩码、默认网关等关键网络配置参数。DHCP 服务器集中管理这些配置数据,由网络管理员针对特定网络环境进行设置,并通过 DHCP 消息与客户端通信(见 README.md 的说明)。

在多服务器部署场景中,Windows DHCP 服务支持故障转移(Failover):两台服务器(主服务器 Primary Server 与辅助服务器 Secondary Server)通过一条"故障转移关系"(Failover Relationship)共享一个或多个作用域(Scope)。当其中一台服务器不可用时,另一台接管地址分配。从本仓库 CreateRelationship 示例源码 可以看到,一条关系包含以下关键属性:

  • RelationshipName:关系名称(如"test");
  • PrimaryServer/SecondaryServer:主、辅服务器 IP 地址(源码中0xa000001即10.0.0.1);
  • PrimaryServerName/SecondaryServerName:主、辅服务器名称;
  • Mode:关系模式,取LoadBalance(负载均衡)或HotStandby(热备);
  • Mclt:Maximum Client Lead Time,客户端最大前导时间(示例中0xe10= 3600 秒);
  • SafePeriod:安全期(0x258= 600 秒);
  • Percentage:负载均衡百分比(0x32= 50%);
  • SharedSecret:主辅服务器间的共享机密;
  • pScopes:该关系所包含的作用域 IP 数组(DHCP_IP_ARRAY结构)。

EnumRelationship 示例正是解决"如何枚举一台服务器上已存在的所有这类关系"这一问题,它所调用的DhcpV4FailoverEnumRelationship属于DHCP Server Management API中Dhcpv4Failover系列函数。

二、示例工程结构与系统要求

2.1 文件布局

该示例在仓库中的目录结构如下:

路径作用
Samples/DHCP/EnumRelationship/README.md示例说明文档
Samples/DHCP/EnumRelationship/cpp/EnumRelationship.cpp唯一源码文件,完整演示枚举调用
Samples/DHCP/EnumRelationship/cpp/EnumRelationship.slnVisual Studio 解决方案文件
Samples/DHCP/EnumRelationship/cpp/EnumRelationship.vcxproj项目文件

2.2 操作系统与开发环境要求

README 明确列出的环境要求为:

  • 客户端:Windows 8.1;
  • 服务器:Windows Server 2012 R2;
  • 开发工具:Visual Studio Express 2013 for Windows 8.1 或更新版本(README 同时说明,多数情况下使用更高版本工具链可无修改运行)。

从 EnumRelationship.vcxproj 可以进一步确认工程级配置:

  • 仅提供x64平台的 Debug / Release 两个配置;
  • 工具集PlatformToolset为v110(对应 Visual Studio 2012/2013 工具链);
  • CharacterSet为Unicode,预处理器定义包含WIN32_LEAN_AND_MEAN、UNICODE、_UNICODE等;
  • 链接器通过AdditionalOptions显式引入dhcpsapi.lib(DHCP Server 管理 API 的导入库),子系统为Console(控制台程序);
  • 编译警告级别为 Level4,并将警告视为错误(TreatWarningAsError=true)。

这些配置意味着:示例是一个面向 x64、Unicode 字符集、依赖dhcpsapi.h头文件的控制台应用,运行前必须保证目标 Windows 具备 DHCP Server 管理 API 支持。

三、核心原理:分页式的枚举调用模式

DhcpV4FailoverEnumRelationship与常见的 Windows 枚举类 API(如EnumServicesStatusEx)一样,采用"分页(paging)"协议:服务器不会一次返回全部数据,而是按批返回,调用方通过循环持续拉取直到取完。

从 EnumRelationship.cpp 主函数 可以看出实际调用形式:

dwError = DhcpV4FailoverEnumRelationship( pwszServer, // 服务器 IP 地址;NULL 表示当前本机 &resumeHandle, // 断点句柄,首次调用为 0,后续调用回传更新值 preferredMax, // 单批期望最大条数;DWORD_MAX 表示采用服务器默认分页大小 &enumRelationInfo, // 输出:本次返回的关系数组 &dwElementsRead, // 输出:本次实际读取到的关系条数 &dwElementsTotal); // 输出:服务器上关系总数

各参数含义归纳如下:

参数方向说明
ServerIpAddress(pwszServer)入目标 DHCP 服务器的 IP 地址字符串;传NULL代表当前执行程序所在的服务器
ResumeHandle(resumeHandle)入/出分页续传句柄。首轮调用置 0,之后由 API 写入新值,下一轮调用原样回传
PreferredMaximum(preferredMax)入调用方期望单批返回的最大条数;示例传DWORD_MAX,即不限制,交由服务器决定
EnumRelationshipInfo(enumRelationInfo)出指向LPDHCP_FAILOVER_RELATIONSHIP_ARRAY,接收本批关系数据
ElementsRead(dwElementsRead)出本批实际读到的关系条数
ElementsTotal(dwElementsTotal)出服务器上关系总数(用于判断是否已取完)

3.1 返回值语义与循环终止条件

示例 源码的错误处理段 展示了三种关键返回码的配合:

  • ERROR_SUCCESS(NO_ERROR):本批成功返回;
  • ERROR_MORE_DATA:还有更多数据未取完,应携带更新的resumeHandle继续循环;
  • ERROR_NO_MORE_ITEMS:已无更多条目,枚举结束。

循环逻辑为:

for(;;) { dwError = DhcpV4FailoverEnumRelationship(...); // 1) 除上述三种返回码外的任何错误,打印后直接终止 if ((NO_ERROR != dwError) && (ERROR_MORE_DATA != dwError) && (ERROR_NO_MORE_ITEMS != dwError )) { wprintf(L"Error in enumerating relationships. Error = %d\n", dwError); break; } // 2) 处理本批数据(见下文第四节) if (dwElementsRead && enumRelationInfo) { ... FreeDhcpFailoverRelationshipArray(enumRelationInfo); enumRelationInfo = NULL; } // 3) 取完的标志:返回 ERROR_NO_MORE_ITEMS,或 SUCCESS 且总数为 0 if (ERROR_NO_MORE_ITEMS == dwError || (dwError == ERROR_SUCCESS && dwElementsTotal == 0)) { dwError = ERROR_SUCCESS; break; } // 4) 重置计数,进入下一轮 dwElementsRead = 0; dwElementsTotal = 0; }

这段代码是"分页枚举"的通用模板:每轮处理完数据后立即释放输出内存,随后依据返回码决定是否继续,直到收到ERROR_NO_MORE_ITEMS或确认总数已取尽。dwElementsRead在本批没有数据时为 0,enumRelationInfo也为 NULL,因此示例用if (dwElementsRead && enumRelationInfo)双重判断后再进入数据处理分支,避免对空指针解引用。

四、完整源码逐段精讲

4.1 头文件与依赖

EnumRelationship.cpp 顶部包含:

#include<windows.h> #include<stdio.h> #include<intsafe.h> // 安全整数运算辅助头 #include<dhcpsapi.h> // DHCP Server 管理 API 声明,如 DhcpV4FailoverEnumRelationship

其中dhcpsapi.h是使用本系列 API 的必经头文件,它声明了DHCP_FAILOVER_RELATIONSHIP、DHCP_FAILOVER_RELATIONSHIP_ARRAY、DHCP_IP_ARRAY等数据结构以及DhcpV4Failover*系列函数原型。

4.2 内存释放辅助函数

API 通过 RPC 返回的数据使用DhcpRpcFreeMemory释放,这是 DHCP Server 管理 API 家族的通用约定。示例为此编写了三个层次分明的释放函数:

  • FreeIPArray:释放LPDHCP_IP_ARRAY,先释放内部Elements数组,再释放结构本身;
  • FreeDhcpFailoverRelationship:释放单条关系。先逐个释放RelationshipName、PrimaryServerName、SecondaryServerName、pScopes、SharedSecret等字符串与数组成员,再释放关系结构本体(重载了"按值"与"按指针"两种形式);
  • FreeDhcpFailoverRelationshipArray:遍历DHCP_FAILOVER_RELATIONSHIP_ARRAY的pRelationships数组,逐条调用上面的释放函数,最后释放数组本体。

这一组函数是枚举示例的关键配套代码:凡是 API 输出的堆内存,都必须用DhcpRpcFreeMemory精确释放,否则会产生内存泄漏。可以对照 GetRelationship 示例 中结构相同的FreeRelationshipMemory佐证这一内存管理约定。

4.3 枚举结果的处理

示例对每批返回的数据做了最简示范——打印每条关系的名称:

for ( dwIdx = 0; dwIdx < enumRelationInfo->NumElements; dwIdx++ ) { wprintf(L"Relationship name = %s\n", enumRelationInfo->pRelationships[dwIdx].RelationshipName); }

DHCP_FAILOVER_RELATIONSHIP_ARRAY结构的两个字段在此处被使用:

  • NumElements:本数组中关系条数;
  • pRelationships:DHCP_FAILOVER_RELATIONSHIP数组指针,每个元素即一条完整的关系描述(含名称、主辅服务器、模式、MCLT、SafePeriod、百分比、共享机密、作用域列表等字段)。

实际业务中,你可以在循环内根据RelationshipName做筛选、比对或驱动后续操作,例如进一步调用DhcpV4FailoverGetRelationship获取单条关系明细、调用DhcpV4FailoverSetRelationship修改参数等。处理完毕后务必调用FreeDhcpFailoverRelationshipArray释放本批内存并将指针置 NULL。

五、DhcpV4Failover 关系 API 家族与本示例的定位

DhcpV4FailoverEnumRelationship并非孤立 API,它属于 DHCP Server Management API 中管理故障转移关系的一组函数。Windows-classic-samples 仓库在 Samples/DHCP 目录下为这一家族提供了成系列的配套示例,可作为枚举结果的"后续动作"参考:

示例目录使用的 API源码要点
GetRelationshipDhcpV4FailoverGetRelationship按关系名"test"查询单条关系,演示DhcpRpcFreeMemory释放模式
SetRelationshipDhcpV4FailoverGetRelationship+DhcpV4FailoverSetRelationship先取回关系,再通过dwFlags(MODE、SAFEPERIOD、MCLT、PERCENTAGE位)指定要修改的字段
CreateRelationshipDhcpV4FailoverCreateRelationship/DhcpV4FailoverDeleteRelationship完整构造DHCP_FAILOVER_RELATIONSHIP(含pScopes作用域数组),并在主辅服务器上先后建关系
DeleteRelationshipDhcpV4FailoverGetRelationship+DhcpV4FailoverDeleteRelationship删除前先停用相关作用域,主、辅服务器分别删除
GetScopeRelationshipDhcpV4FailoverGetScopeRelationship按作用域子网地址(如10.0.0.0)反查所属关系

从这些源码可以推断:一条完整的关系生命周期通常是"创建(Create)→ 枚举(Enum)→ 查询(Get)→ 修改(Set)→ 删除(Delete)",而EnumRelationship 示例正是"枚举"环节的标准实现范本,其分页循环与内存释放模式可以被其他枚举类 DHCP 管理 API(如DhcpV4EnumPolicies对应仓库中的 EnumPolicy 示例)直接复用。

六、构建与运行

6.1 构建

按 README.md 的说明:

  1. 使用 Visual Studio Express 2013 for Windows 8.1 或更高版本打开解决方案文件 EnumRelationship.sln;
  2. 从顶部菜单执行Build → Build Solution(Visual Studio 2013 中为 F6,其余版本通常为 F7);
  3. 编译产物默认输出到Debug或Release目录(本工程为 x64 平台下的x64\Debug或x64\Release)。

工程使用v110工具集并链接dhcpsapi.lib,构建时需确保 Windows SDK 提供 DHCP 管理头文件与导入库;更高版本 Visual Studio 打开工程后如提示工具集升级,可按默认处理。

6.2 运行

在 Visual Studio 中按F5(启用调试运行)或Ctrl+F5(不启用调试运行),也可通过Debug菜单选择相应选项。

运行前提与限制(README 与源码共同确认):

  • 操作系统需为 Windows 8.1 / Windows Server 2012 R2 及兼容版本;
  • 目标机器需具备 DHCP 服务器管理能力(本 API 由 DHCP Server 管理服务承载);
  • pwszServer传NULL时枚举的是当前执行程序所在机器的 DHCP 服务器,如需枚举远程服务器,可将该参数改为目标服务器的 IP 地址字符串;
  • 程序以控制台方式运行,枚举结果(关系名称)逐条打印到标准输出;返回码ERROR_NO_MORE_ITEMS或ERROR_SUCCESS且总数为 0 时正常结束。

七、总结

DhcpV4FailoverEnumRelationship是 Windows DHCP 故障转移管理中的核心枚举接口。通过 EnumRelationship 示例 可以学到一套可复用的标准模式:

  1. 分页调用:resumeHandle配合ERROR_MORE_DATA循环拉取,直到ERROR_NO_MORE_ITEMS;
  2. 输出约束:preferredMax = DWORD_MAX交由服务器决定批次大小,ElementsRead/ElementsTotal用于统计与终止判断;
  3. 内存纪律:所有输出结构必须经DhcpRpcFreeMemory逐层释放;
  4. 家族协同:与DhcpV4FailoverGetRelationship、DhcpV4FailoverSetRelationship、DhcpV4FailoverCreateRelationship、DhcpV4FailoverDeleteRelationship、DhcpV4FailoverGetScopeRelationship共同构成关系管理的完整闭环。

后续可在仓库 Samples/DHCP 目录下继续研读上述配套示例,将枚举结果接入真实的运维与自动化管理流程。

  • 示例工程

【免费下载链接】Windows-classic-samples

This repo contains samples that demonstrate the API used in Windows classic desktop applications.

项目地址:https://gitcode.com/gh_mirrors/wi/Windows-classic-samples
点击查看免费下载
上一篇:终端美化神器:awesome-hyper主题使用心得分享
下一篇:IntelliJ IDEA 简体中文专题教程:从安装、配置到高效开发的全路径学习指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询