WindowsAPI|每天了解几个winAPI接口之网络配置相关文档Iphlpapi.h详细分析10

上一篇:WindowsAPI|每天了解几个winAPI接口之网络配置相关文档Iphlpapi.h详细分析9
如果有错误欢迎指正批评,在此只作为科普和参考。

C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um\iphlpapi.h

文章目录

  • GetNetworkParams:一次性拿到本机“全局固定”的 IPv4 网络参数——主机名、域名、DNS 服务器列表、节点类型、是否启用路由/代理等
      • 1. 函数原型
      • 2. 返回的核心结构 `FIXED_INFO`
      • 3. 最小示例
      • 4. 常见错误码
      • 5. 典型用途
      • 6. 限制与注意
  • GetAdaptersInfo&GetAdapterOrderMap:把本机 所有 IPv4 网卡 的 完整信息一次性打包返回&给出 “连接顺序”(绑定顺序 / 路由优先级)里 各网卡接口索引 的先后列表。
      • 一、GetAdaptersInfo
        • 1. 原型
        • 2. 返回的核心结构
        • 3. 最小示例
      • 二、GetAdapterOrderMap
        • 1. 原型
        • 2. 返回结构
        • 3. 最小示例
      • 三、何时用哪个?
  • GetAdaptersAddresses:通过 Winsock2 API 获取本地网络适配器的地址信息
      • ✅ 条件编译块
      • ✅ Winsock2 依赖检查
      • ✅ 函数声明
      • ✅ 使用场景
      • ✅ 示例代码(简化版)
  • GetPerAdapterInfo:查某个网卡的 DHCP/WINS/DNS 服务器地址
      • ✅ 条件编译
      • ✅ 函数原型
      • ✅ 作用
      • ✅ 结构体定义(简要)
      • ✅ 使用步骤(伪代码)
      • ✅ 注意
      • ✅ 总结一句话
  • 网络接口硬件时间戳能力(hardware timestamping)

GetNetworkParams:一次性拿到本机“全局固定”的 IPv4 网络参数——主机名、域名、DNS 服务器列表、节点类型、是否启用路由/代理等

#pragma region Application Family or OneCore Family or Games Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)#if (NTDDI_VERSION >= NTDDI_WIN2KSP1)
IPHLPAPI_DLL_LINKAGE
DWORD
WINAPI
GetNetworkParams(_Out_writes_bytes_opt_(*pOutBufLen)   PFIXED_INFO pFixedInfo,_Inout_                         PULONG      pOutBufLen);
#endif#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion

GetNetworkParams 的作用是:
一次性拿到本机“全局固定”的 IPv4 网络参数——主机名、域名、DNS 服务器列表、节点类型、是否启用路由/代理等。


1. 函数原型

DWORD WINAPI GetNetworkParams(_Out_writes_bytes_opt_(*pOutBufLen) PFIXED_INFO pFixedInfo,_Inout_                             PULONG      pOutBufLen
);
  • pFixedInfo
    调用者提供的缓冲区;可传 NULL 做“两次调用”套路:
    第一次返回所需字节数,第二次真正取数据。
  • pOutBufLen
    输入时给出缓冲区大小,输出时返回实际需要的字节数。

2. 返回的核心结构 FIXED_INFO

typedef struct _FIXED_INFO {char     HostName[MAX_HOSTNAME_LEN + 4];char     DomainName[MAX_DOMAIN_NAME_LEN + 4];PIP_ADDR_STRING CurrentDnsServer;   // 链表首节点IP_ADDR_STRING  DnsServerList;      // 第一个 DNS 地址UINT     NodeType;                  // BROADCAST/PEER/HYBRID/MIXEDchar     ScopeId[MAX_SCOPE_ID_LEN + 4];UINT     EnableRouting;             // 1=充当 IP 路由器UINT     EnableProxy;               // 1=启用 DNS 代理(废弃)UINT     EnableDns;                 // 1=启用 DNS
} FIXED_INFO, *PFIXED_INFO;
  • 所有字符串都是 ANSIchar)。
  • DNS 服务器以 单向链表 形式挂接:DnsServerList.Next → IP_ADDR_STRING*
  • EnableProxy 字段在 Win10 后已作废,始终为 0。

3. 最小示例

ULONG sz = 0;
GetNetworkParams(nullptr, &sz);          // 第一次取大小
auto buf = std::make_unique<BYTE[]>(sz);
auto p   = reinterpret_cast<PFIXED_INFO>(buf.get());DWORD ret = GetNetworkParams(p, &sz);
if (ret == NO_ERROR) {printf("Host : %s\n", p->HostName);printf("Domain: %s\n", p->DomainName);for (auto cur = &p->DnsServerList; cur; cur = cur->Next) {printf("DNS: %s\n", cur->IpAddress.String);}
} else {printf("GetNetworkParams failed: %lu\n", ret);
}

4. 常见错误码

含义
ERROR_BUFFER_OVERFLOW缓冲区太小(第一次正常)
ERROR_NO_DATATCP/IP 协议未安装
ERROR_INVALID_PARAMETER指针为空

5. 典型用途

  • 网络诊断工具:快速列出本机 DNS 配置。
  • DNS 切换器:确认当前主 DNS 地址后决定是否替换。
  • 零配置服务:读取主机名、域名、节点类型做 NetBIOS 发现。

6. 限制与注意

  • IPv4 参数;IPv6 DNS 需用 GetAdaptersAddresses
  • 静态信息:不会实时更新 DHCP 续租后的变化,需重调一次。
  • ANSI 字符串:若要 Unicode,需自行转换。

一句话总结
GetNetworkParams 就是“一键取本机 IPv4 全局网络名片”:主机名、域名、全部 DNS 服务器、节点类型等一次打包返回。

GetAdaptersInfo&GetAdapterOrderMap:把本机 所有 IPv4 网卡 的 完整信息一次性打包返回&给出 “连接顺序”(绑定顺序 / 路由优先级)里 各网卡接口索引 的先后列表。

#pragma region Desktop Family or OneCore Family or Games Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)IPHLPAPI_DLL_LINKAGE
ULONG
WINAPI
GetAdaptersInfo(_Out_writes_bytes_opt_(*SizePointer) PIP_ADAPTER_INFO AdapterInfo,_Inout_                         PULONG           SizePointer);IPHLPAPI_DLL_LINKAGE
PIP_ADAPTER_ORDER_MAP
WINAPI
GetAdapterOrderMap(VOID);#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion

下面两个 API 都来自 iphlpapi.dll,但用途完全不同。
一句话区分:

API一句话功能
GetAdaptersInfo把本机 所有 IPv4 网卡完整信息(MAC、IP、网关、DHCP、WINS…)一次性打包返回。
GetAdapterOrderMap给出 “连接顺序”(绑定顺序 / 路由优先级)里 各网卡接口索引 的先后列表。

一、GetAdaptersInfo

1. 原型
ULONG WINAPI GetAdaptersInfo(_Out_writes_bytes_opt_(*SizePointer) PIP_ADAPTER_INFO AdapterInfo,_Inout_ PULONG SizePointer
);
  • 经典“两次调用”流程:
    ① 第一次把 AdapterInfoNULL,拿到所需字节数;
    ② 第二次真正取数据。
  • 仅 IPv4;需要 IPv6 请用 GetAdaptersAddresses
2. 返回的核心结构
typedef struct _IP_ADAPTER_INFO {struct _IP_ADAPTER_INFO* Next;           // 链表下一项DWORD ComboIndex;                        // 保留char  AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];char  Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];UINT  AddressLength;                     // MAC 地址长度BYTE  Address[MAX_ADAPTER_ADDRESS_LENGTH];// MAC 地址DWORD Index;                             // ifIndexUINT  Type;                              // MIB_IF_TYPE_XXXUINT  DhcpEnabled;                       // 1=DHCPPIP_ADDR_STRING CurrentIpAddress;        // 当前地址IP_ADDR_STRING IpAddressList;            // 所有 IPv4 地址链表IP_ADDR_STRING GatewayList;              // 默认网关链表IP_ADDR_STRING DhcpServer;               // DHCP 服务器BOOL  HaveWins;                          // 是否启用 WINSIP_ADDR_STRING PrimaryWinsServer;IP_ADDR_STRING SecondaryWinsServer;time_t LeaseObtained;time_t LeaseExpires;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
3. 最小示例
ULONG sz = 0;
GetAdaptersInfo(nullptr, &sz);
auto buf = std::make_unique<BYTE[]>(sz);
auto p   = reinterpret_cast<PIP_ADAPTER_INFO>(buf.get());
if (GetAdaptersInfo(p, &sz) == ERROR_SUCCESS) {for (auto cur = p; cur; cur = cur->Next) {printf("Idx=%lu  MAC=%02X-%02X-%02X-%02X-%02X-%02X  Desc=%s\n",cur->Index,cur->Address[0], cur->Address[1], cur->Address[2],cur->Address[3], cur->Address[4], cur->Address[5],cur->Description);for (auto ip = &cur->IpAddressList; ip; ip = ip->Next)printf("  IPv4=%s/%s\n", ip->IpAddress.String, ip->IpMask.String);}
}

二、GetAdapterOrderMap

1. 原型
PIP_ADAPTER_ORDER_MAP WINAPI GetAdapterOrderMap(VOID);
  • 直接返回一个 全局静态结构体指针,无需两次调用,无需释放。
  • 失败返回 NULL
2. 返回结构
typedef struct _IP_ADAPTER_ORDER_MAP {ULONG NumAdapters;ULONG AdapterOrder[1];   // 柔性数组,NumAdapters 个 ifIndex
} IP_ADAPTER_ORDER_MAP, *PIP_ADAPTER_ORDER_MAP;
  • AdapterOrder[0] 是绑定顺序 最高(默认路由最先匹配)的接口;
    依次递减。
  • netsh interface ipv4 show interfaces level=verbose 里看到的 “InterfaceMetric” 顺序一致。
3. 最小示例
auto order = GetAdapterOrderMap();
if (order) {for (ULONG i = 0; i < order->NumAdapters; ++i)printf("Order[%lu] = IfIndex %lu\n", i, order->AdapterOrder[i]);
}

三、何时用哪个?

需求推荐 API
枚举 IPv4 网卡、MAC、IP、网关、DHCP、WINSGetAdaptersInfo
需要 IPv6、DNS、Gateway、DNS suffix、MTU 等更全信息GetAdaptersAddresses
只想知道“连接顺序”/路由优先级GetAdapterOrderMap

一句话总结

  • GetAdaptersInfo 像“网卡体检报告”;
  • GetAdapterOrderMap 像“路由优先级排行榜”。

GetAdaptersAddresses:通过 Winsock2 API 获取本地网络适配器的地址信息

#pragma region Application Family or OneCore Family or Games Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)#ifdef _WINSOCK2API_//
// The following functions require Winsock2.
//IPHLPAPI_DLL_LINKAGE
ULONG
WINAPI
GetAdaptersAddresses(_In_ ULONG Family,_In_ ULONG Flags,_Reserved_ PVOID Reserved,_Out_writes_bytes_opt_(*SizePointer) PIP_ADAPTER_ADDRESSES AdapterAddresses,_Inout_ PULONG SizePointer);#endif

它的作用是通过 Winsock2 API 获取本地网络适配器的地址信息。

解释一下这段代码的结构和含义:


✅ 条件编译块

#pragma region Application Family or OneCore Family or Games Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)
  • 这是为了控制函数在不同 Windows 平台(如桌面、UWP、Xbox、HoloLens 等)上的可见性。
  • 只有目标平台支持 APPSYSTEMGAMES 分区时,这段代码才会被编译。

✅ Winsock2 依赖检查

#ifdef _WINSOCK2API_
  • 只有在包含了 <winsock2.h>(即 _WINSOCK2API_ 被定义)时,GetAdaptersAddresses 才会被声明。
  • 避免与早期 Winsock 1.x 冲突。

✅ 函数声明

IPHLPAPI_DLL_LINKAGE
ULONG
WINAPI
GetAdaptersAddresses(_In_ ULONG Family,_In_ ULONG Flags,_Reserved_ PVOID Reserved,_Out_writes_bytes_opt_(*SizePointer) PIP_ADAPTER_ADDRESSES AdapterAddresses,_Inout_ PULONG SizePointer
);

这是 GetAdaptersAddresses 的标准 C 接口声明:

参数名含义
Family地址族,如 AF_INET(IPv4)、AF_INET6(IPv6)或 AF_UNSPEC(两者都包括)
Flags控制返回信息的类型,如是否包括 DNS 后缀、是否跳过回环接口等
Reserved保留参数,必须为 NULL
AdapterAddresses输出缓冲区,用于接收 IP_ADAPTER_ADDRESSES 结构体链表
SizePointer输入输出参数,传入缓冲区大小,返回实际所需大小

✅ 使用场景

你可以用 GetAdaptersAddresses 来获取本机的网络接口信息,比如:

  • IP 地址(IPv4/IPv6)
  • MAC 地址
  • DNS 服务器
  • 网关
  • 接口描述、类型、状态等

✅ 示例代码(简化版)

#include <winsock2.h>
#include <iphlpapi.h>
#include <iostream>#pragma comment(lib, "iphlpapi.lib")int main() {ULONG size = 0;GetAdaptersAddresses(AF_UNSPEC, 0, nullptr, nullptr, &size);PIP_ADAPTER_ADDRESSES adapters = (PIP_ADAPTER_ADDRESSES)malloc(size);if (GetAdaptersAddresses(AF_UNSPEC, 0, nullptr, adapters, &size) == ERROR_SUCCESS) {for (auto* p = adapters; p; p = p->Next) {std::wcout << L"Adapter: " << p->FriendlyName << std::endl;}}free(adapters);return 0;
}

GetPerAdapterInfo:查某个网卡的 DHCP/WINS/DNS 服务器地址

#if (NTDDI_VERSION >= NTDDI_WIN2KSP1)
IPHLPAPI_DLL_LINKAGE
DWORD
WINAPI
GetPerAdapterInfo(_In_                            ULONG                IfIndex,_Out_writes_bytes_opt_(*pOutBufLen)   PIP_PER_ADAPTER_INFO pPerAdapterInfo,_Inout_                         PULONG               pOutBufLen);
#endif#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion

它和 GetAdaptersAddresses 一样,也受平台分区(App / System / Games)和 Windows 版本(NTDDI_WIN2KSP1 及以上)的限制。


✅ 条件编译

#if (NTDDI_VERSION >= NTDDI_WIN2KSP1)
  • 只有目标系统的 SDK 版本 ≥ Windows 2000 SP1 时,这段声明才会被编译。
  • 防止在老系统上调用不存在的 API。

✅ 函数原型

IPHLPAPI_DLL_LINKAGE
DWORD
WINAPI
GetPerAdapterInfo(_In_  ULONG                IfIndex,          // 接口索引_Out_writes_bytes_opt_(*pOutBufLen) PIP_PER_ADAPTER_INFO pPerAdapterInfo,_Inout_ PULONG               pOutBufLen       // 缓冲区大小/返回所需大小
);

✅ 作用

获取 指定网络接口(由 IfIndex 标识) 的“每适配器”信息,主要包括:

  • DHCP 服务器地址
  • 主/备 WINS 服务器地址
  • 是否启用 DHCP / WINS

✅ 结构体定义(简要)

typedef struct _IP_PER_ADAPTER_INFO {UINT autoconfigEnabled;     // 是否启用自动配置UINT autoconfigActive;      // 是否正在使用自动配置PIP_ADDR_STRING currentDnsServer; // 当前 DNS 服务器IP_ADDR_STRING dnsServerList;     // DNS 服务器链表UINT nodeType;              // 节点类型(B、P、M、H)SCOPE_ID scopeId;           // NetBIOS scope IDUINT enableRouting;         // 是否启用路由UINT enableProxy;           // 是否启用代理UINT enableDns;             // 是否启用 DNS
} IP_PER_ADAPTER_INFO, *PIP_PER_ADAPTER_INFO;

✅ 使用步骤(伪代码)

ULONG idx = 5;  // 假设已知接口索引
ULONG size = 0;
GetPerAdapterInfo(idx, nullptr, &size);          // 先拿大小
auto* info = (PIP_PER_ADAPTER_INFO)malloc(size);
if (GetPerAdapterInfo(idx, info, &size) == ERROR_SUCCESS) {printf("DHCP server: %s\n", info->dhcpServer.IpAddress.String);
}
free(info);

✅ 注意

  1. IfIndex 必须通过 GetAdaptersInfoGetAdaptersAddresses 提前拿到。
  2. 该 API 不支持 IPv6,只针对 IPv4 接口。
  3. 返回的 DNS 服务器列表是 单链表,需要遍历 dnsServerList.Next

✅ 总结一句话

GetPerAdapterInfo 是“老派”IPv4 专用接口,用来查某个网卡的 DHCP/WINS/DNS 服务器地址;新项目建议优先用 GetAdaptersAddresses,它覆盖 IPv4/IPv6 且信息更全面。

网络接口硬件时间戳能力(hardware timestamping)

#pragma region Desktop Family or OneCore Family or Games Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)#if (NTDDI_VERSION >= NTDDI_WIN10_FE)typedef struct _INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES
{BOOLEAN PtpV2OverUdpIPv4EventMessageReceive;BOOLEAN PtpV2OverUdpIPv4AllMessageReceive;BOOLEAN PtpV2OverUdpIPv4EventMessageTransmit;BOOLEAN PtpV2OverUdpIPv4AllMessageTransmit;BOOLEAN PtpV2OverUdpIPv6EventMessageReceive;BOOLEAN PtpV2OverUdpIPv6AllMessageReceive;BOOLEAN PtpV2OverUdpIPv6EventMessageTransmit;BOOLEAN PtpV2OverUdpIPv6AllMessageTransmit;BOOLEAN AllReceive;BOOLEAN AllTransmit;BOOLEAN TaggedTransmit;
} INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES, *PINTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES;typedef struct _INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES
{BOOLEAN AllReceive;BOOLEAN AllTransmit;BOOLEAN TaggedTransmit;
} INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES, *PINTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES;typedef struct _INTERFACE_TIMESTAMP_CAPABILITIES
{ULONG64 HardwareClockFrequencyHz;BOOLEAN SupportsCrossTimestamp;INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES HardwareCapabilities;INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES SoftwareCapabilities;
} INTERFACE_TIMESTAMP_CAPABILITIES, *PINTERFACE_TIMESTAMP_CAPABILITIES;typedef struct _INTERFACE_HARDWARE_CROSSTIMESTAMP
{ULONG64 SystemTimestamp1;ULONG64 HardwareClockTimestamp;ULONG64 SystemTimestamp2;
} INTERFACE_HARDWARE_CROSSTIMESTAMP, *PINTERFACE_HARDWARE_CROSSTIMESTAMP;DECLARE_HANDLE(HIFTIMESTAMPCHANGE);

这段是 Windows SDK 10.0.19041(Win10 FE=“Fall Edition”,即 20H1)以后才出现的 网络接口硬件时间戳能力(hardware timestamping) 相关定义。它只会在:

  • 目标平台分区包含 Desktop / System / Games
  • 且 SDK 版本 ≥ NTDDI_WIN10_FE(20H1,10.0.19041)

时才会被编译器看到。

下面把几个结构体按“谁干什么用”快速梳理一下。

────────────────────────

  1. 能力描述结构体
    ────────────────────────
    INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES
    INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES
    INTERFACE_TIMESTAMP_CAPABILITIES
  • 通过 GetAdaptersAddresses 的新标志 GAA_FLAG_INCLUDE_TIMESTAMP 返回,位于 IP_ADAPTER_ADDRESSES::HardwareTimestampCapabilities 字段。
  • 用来告诉调用者:
    ‑ 该 NIC 的硬件时钟频率(HardwareClockFrequencyHz)
    ‑ 是否支持“交叉时间戳”(见下文)
    ‑ 支持哪些 PTP(IEEE 1588 v2)报文类型、UDP/IPv4 还是 IPv6、RX 还是 TX、是否支持“Tagged”时间戳(VLAN/QoS 标记)
    ‑ 软件时间戳能力(内核软件栈能否打时间戳)

────────────────────────
2. 交叉时间戳结构体
────────────────────────
INTERFACE_HARDWARE_CROSSTIMESTAMP

  • 用于把 系统 QPC(QueryPerformanceCounter)NIC 本地硬件时钟 做一次“同步采样”。
  • 通过新的 IOCTL IOCTL_NSI_GET_CROSS_TIMESTAMP(或未来 SDK 暴露的 API)一次性返回 3 个 64-bit 值:
    SystemTime1 → HardwareClock → SystemTime2
  • 应用程序用简单线性插值就可以把 NIC 时间戳线性地映射到系统时间,实现亚毫秒级同步。

────────────────────────
3. 句柄声明
────────────────────────
DECLARE_HANDLE(HIFTIMESTAMPCHANGE);

  • 这是一个不透明句柄,用于注册“时间戳能力变化”通知(类似网络状态变化回调)。
  • 目前公开文档中尚未给出配套的 API 原型,估计未来会和 NotifyInterfaceTimestampChange 之类的新函数一起放出。

────────────────────────
4. 小结(一句话)
────────────────────────
这些定义是 Win10 20H1+ 新增的 NIC 硬件时间戳能力系统-硬件时钟同步 接口,专为高精度时间同步(PTP、金融交易、工业控制、5G)场景服务;普通应用不会用到,但如果你要写 PTP 客户端或者做纳秒级测量的驱动/服务,就得关心它们。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/95611.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/95611.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法 --- 分治(归并)

分治&#xff08;归并&#xff09; 分治&#xff08;特别是归并&#xff09;算法适用于解决“整体求解依赖于子问题合并”且子问题相互独立的题目&#xff0c;其典型特征是能将大规模数据分解、递归求解&#xff0c;然后通过合并操作&#xff08;这正是归并排序中‘归并’的精…

【程序人生】有梦想就能了不起,就怕你没梦想

梦想不是遥不可及的星辰&#xff0c;而是需要我们用脚步丈量的路途两年前的一个夏日&#xff0c;我在日记本上郑重地写下&#xff1a;"我要掌握Web开发&#xff0c;能够独立构建一个完整的Web应用。"那天是2023年6月8日&#xff0c;当时的我连Java和JavaScript都分不…

前端基础(四十二):非固定高度的容器实现折叠面板效果

效果展示源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head>…

发票、收据合并 PDF 小程序,报销上传 3 秒搞定

每到报销、报税、财务整理时&#xff0c;手里是不是总有一堆格式不一的票据&#xff1a; 聊天记录里的电子发票邮件附件中的 PDF 发票手机相册里的报销收据甚至还有零散的纸质票据扫描件 要上传或交给财务前&#xff0c;还得一个个整理、转换、排版&#xff0c;既耗时又容易出…

GitHub每日最火火火项目(9.4)

1. bytebot-ai / bytebot 项目名称&#xff1a;bytebot项目介绍&#xff1a;基于 TypeScript 开发&#xff0c;是一款自托管的 AI 桌面智能体&#xff0c;能通过自然语言命令自动化执行计算机任务&#xff0c;运行在容器化的 Linux 桌面环境中。它借助自然语言处理和 AI 技术&a…

MMORPG 游戏战斗系统架构

&#x1f30c; MMORPG 游戏战斗系统架构 引用&#xff1a; 游戏服务器同步技术解析&#xff08;C&#xff09;MMORPG移动同步与反外挂 虽然我已离开游戏行业&#xff0c;转而与几位成功的商人共同创业&#xff0c;投身于商用机器人领域&#xff0c;但坦诚地说&#xff0c;游戏…

【数学建模学习笔记】启发式算法:蒙特卡洛算法

蒙特卡洛模拟入门笔记&#xff1a;从原理到代码实践一、什么是蒙特卡洛模拟&#xff1f;蒙特卡洛模拟是一种通过大量随机实验来解决复杂问题的方法。简单说&#xff0c;就是用电脑模拟成千上万次随机事件&#xff0c;然后统计结果&#xff0c;以此估算一个问题的答案。举个生活…

20250904的学习笔记

一、封包与拆包1. 封包&#xff08;Packet Encapsulation&#xff09;封包 是指在发送数据时&#xff0c;将数据从高层协议封装到低层协议的过程。每经过一层协议&#xff0c;数据都会被加上相应的协议头&#xff08;有时也会加上协议尾&#xff09;&#xff0c;形成一个新的数…

STM32F4 + RT-Thread 实战指南:TIM10 硬件定时器驱动开发与 1 秒定时功能实现

目录前言一、STM32定时器10是个什么定时器&#xff1f;二、工程创建、环境配置三、程序代码四、运行前言 在rtthread中&#xff0c;STM32F4的定时器10有些驱动并不完整&#xff0c;对比与其它定时器在使用时需要手动的添加一些代码&#xff0c;我在使用上拆踩了一些坑&#xf…

echarts图库

环形图// 指定图表的配置项和数据this.option {// tooltip: {// trigger: item// },color: [#FFB32F, #FF5757, #57D5FF, #2FA8FF, #95FFF1], // 扇形区域以及列表颜色legend: {orient:vertical,//文字横向排itemGap:20,left: left,textStyle:{color: #F3F9FF,// fontSi…

进程(Process)全面概述

进程&#xff08;Process&#xff09;全面概述 本文档扩展了进程的定义、属性、生命周期、管理机制及示例&#xff0c;涵盖 task_struct 结构、进程链表、状态与优先级、fork 函数及其写时复制示例。 一、进程基本概念 进程&#xff1a;系统进行资源分配和调度的基本单位&#…

Java并发编程:sleep()与wait()核心区别详解

今天完成了实验室纳新网站的工作&#xff0c;大体功能都已经完善&#xff0c;也和前端测试过了&#xff0c;费了点时间&#xff0c;而且今天大部分时间在看langchain4j的东西&#xff0c;就简单复习一下八股&#xff0c;等会再复习一下算法题吧在Java并发编程中&#xff0c;sle…

AR眼镜在智能制造的应用方向和场景用例|阿法龙XR云平台

AR巡检在制造业的应用已形成覆盖设备维护、质量检测、安全监控和远程协作四大类别的成熟场景&#xff0c;不同制造领域的实践各具特色&#xff0c;为行业提供了宝贵参考。在汽车制造领域&#xff0c;AR 巡检主要应用于生产线设备维护和焊接质量检测。在汽车厂总装车间部署 AR 系…

【Linux系统】线程同步

在上一章节中&#xff0c;我们使用互斥量之后&#xff0c;确实解决了数据竞争问题&#xff0c;但出现了新的问题&#xff1a;只有一个线程&#xff08;thread 1&#xff09;在处理所有售票任务。这展示了互斥量的一个局限性&#xff1a;它确保了线程安全&#xff0c;但不保证公…

代码随想录训练营第三十一天|LeetCode56.合并区间、LeetCode738.单调递增的数字

56.合并区间 思路&#xff1a;先让二维数组进行排序&#xff1b; 遍历数组&#xff0c;定义一个min表示重合区间的左边界&#xff0c;max表示重合区间的右边界&#xff1b; 如果当前区间左边大于max&#xff0c;就证明重合区间断了&#xff0c;就要对它进行加入ArrayList&am…

【Unity项目经验分享】实现左右分屏裸眼3D程序

1、实现原理左右分屏原理&#xff0c;左右屏内容左右方向存在些许偏差。通过左右相机&#xff0c;然后左侧相机向左侧偏移一点3cm&#xff0c;右侧相机向右侧屏偏移一定3cm&#xff0c;然后将左右相机渲染内容通过RenderTexture渲染到Canvas上面的左右RawImage上面。2、实现具体…

设计软件启动失败?“找不到vcruntime140.dll,无法继续执行代码” 场景化解决方案来了

打游戏时&#xff0c;刚加载到登录界面就因 “找不到 vcruntime140.dll, 无法继续执行代码” 闪退&#xff1b;写代码时&#xff0c;编译工具突然报错中断工作&#xff1b;做设计时&#xff0c;PS、AE 启动失败弹出相同提示 —— 不同场景下的 vcruntime140.dll 错误&#xff0…

基于Echarts+HTML5可视化数据大屏展示-茶叶种植大数据溯源平台

效果展示&#xff1a;代码结构&#xff1a;主要代码实现 index.html布局 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta n…

PLOS One图片处理要求及处理办法

PLOS One图片处理&#xff1a; 要求&#xff1a;Please remove your figures from within your manuscript file, leaving only the individual TIFF/EPS image files. These will be automatically included in the reviewer’s PDF. 请从稿件文件中移除所有图表&#xff0c;…

AutoLayout与Masonry:简化iOS布局

Auto Layout 与 Masonry苹果提供的自动布局&#xff08;Auto Layout&#xff09;能够对视图进行灵活有效的布局。但是&#xff0c;使用原生的自动布局相关的语法创建约束的过程是非常冗长的&#xff0c;可读性也比较差。Masonry 的目标其实就是 为了解决原生自动布局语法冗长的…