一 .前言

        紧接上文,我们继续来阅读httplib库源码。

二 .非Windows操作系统头文件

#include <arpa/inet.h>

        主机序列与网络的大端字节序列的转换函数在这个头文件中。分别是以下四个:

uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);

        h表示主机,n表示网络,l表示long,一般就是4字节ipv4地址,s表示short,一般就是端口。

#if !defined(_AIX) && !defined(__MVS__)         
#include <ifaddrs.h>
#endif

        _AIX__MVS__是IBM的两种操作系统的预定义宏

        #include <ifaddrs.h> 提供一套标准化接口,让程序能便捷获取本机所有网络接口的详细信息(比如网卡名、IP 地址、地址类型、接口状态等),其中有两个核心函数:

  • getifaddrs(struct ifaddrs **ifap):获取所有网络接口信息,结果以链表形式存入 ifap

  • freeifaddrs(struct ifaddrs *ifa):释放 getifaddrs 申请的内存(必须调用,避免内存泄漏)。

        这个头文件中函数的具体作用在源码中用到的时候再详细说明。

#include <net/if.h>

        <net/if.h> 是 POSIX 标准 的网络编程头文件(类 UNIX 系统通用,包括 Linux、macOS、BSD 等),核心作用是:定义与网络接口(网卡) 相关的常量、结构体和辅助函数,是操作网卡基础属性的核心头文件,常与 ioctl() 系统调用、<ifaddrs.h> 配合使用。

#include <netdb.h>

        提供一套标准化接口,实现域名 / 服务名与 IP 地址 / 端口号之间的转换(即 DNS 解析、服务名解析),是网络编程中 “地址解析” 的核心头文件。

#include <netinet/in.h>

        定义与 Internet 协议(TCP/IP) 相关的核心数据结构、常量和字节序转换函数,是编写 TCP/UDP 网络程序的基础。

        简单来说,只要涉及 IPv4/IPv6 地址、端口号、TCP/UDP 套接字编程,几乎都离不开这个头文件。在Linux环境进行socket编程时,这个头文件通常会被间接包含。

#include <resolv.h>

        这是遵循 BSD 标准 的 DNS 编程头文件(Linux/macOS/BSD 通用),核心作用是:提供直接操作 DNS 解析器(resolver) 的底层接口,包括配置 DNS 服务器自定义 DNS 查询(A/AAAA/MX 记录等)、设置解析超时等,是比 <netdb.h> 更底层的 DNS 编程工具。

        简单来说,<netdb.h> 是 “封装好的 DNS 解析工具”(如 getaddrinfo),而 <resolv.h> 是 “手动操控 DNS 解析器的工具箱”,能实现更灵活的 DNS 操作。

#include <csignal>

        C++ 封装的信号处理头文件。

#include <netinet/tcp.h>

        定义 TCP 协议相关选项(如 TCP_NODELAY),配置 TCP 套接字特性。在Linux平台进行socket编程时一般会间接包含。

#include <poll.h>

        提供 poll () 函数,实现 I/O 多路复用。

#include <pthread.h>

        定义线程创建 / 同步。

#include <sys/mman.h>

        <sys/mman.h> 遵循 POSIX 标准,核心作用是:提供一套接口,将文件 / 设备的内容直接映射到进程的虚拟内存空间,或创建匿名内存区域(用于进程间共享内存)。简单来说,它让程序可以像操作普通内存一样操作文件 / 设备,无需调用 read()/write() 等传统 I/O 函数,大幅提升 I/O 效率

#include <sys/socket.h>

        核心套接字编程头文件,定义 socket/bind/listen/accept 等基础网络函数。

#include <sys/un.h>

        定义 Unix 域套接字(AF_UNIX)相关结构体(sockaddr_un)。

#include <unistd.h>

        Unix 标准头文件,提供 read/write/close/fork 等系统调用。

using socket_t = int;
#ifndef INVALID_SOCKET
#define INVALID_SOCKET (-1)
#endif
#endif //_WIN32

        跨平台统一和无效socket的宏定义。

#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif

        苹果系统下精准区分 macOS/iOS/ 模拟器等编译目标。

三.全操作系统公共头文件

#include <algorithm>
#include <array>
#include <atomic>                                // 提供原子类型和原子操作函数
#include <cassert>
#include <cctype>
#include <chrono>                                // C++ 标准库中专门处理时间和日期的头文件
#include <climits>
#include <condition_variable>                    // 实现多线程间的条件同步,让线程按需等待 / 唤醒,避免忙等
#include <cstdlib>
#include <cstring>
#include <errno.h>
#include <exception>
#include <fcntl.h>                               // 操作文件描述符的 “总入口”
#include <functional>
#include <iomanip>                               // 控制 C++ 输入输出流的格式,实现精细化的文本 / 数字打印
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <random>
#include <regex>                                 // 专门处理正则表达式的头文件
#include <set>
#include <sstream>
#include <string>
#include <sys/stat.h>
#include <system_error>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <utility>                               // 提供 C++ 通用工具函数 / 模板

        上面这部分头文件在日常开发中会经常用到,所以只做注释说明。

#if defined(CPPHTTPLIB_USE_NON_BLOCKING_GETADDRINFO) ||                        \
    defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN)
#if TARGET_OS_MAC
#include <CFNetwork/CFHost.h>                    // 提供 macOS/iOS 下的网络地址解析
#include <CoreFoundation/CoreFoundation.h>       // 苹果核心基础框架,提供内存管理、字符串 / 数组等基础类型
#endif
#endif // CPPHTTPLIB_USE_NON_BLOCKING_GETADDRINFO or
       // CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef _WIN32
#include <wincrypt.h>                            // Windows 系统下 CryptoAPI 的核心头文件,提供加密 / 哈希 / 证书相关接口;

// these are defined in wincrypt.h and it breaks compilation if BoringSSL is
// used
#undef X509_NAME
#undef X509_CERT_PAIR
#undef X509_EXTENSIONS
#undef PKCS7_SIGNER_INFO

#ifdef _MSC_VER
#pragma comment(lib, "crypt32.lib")
#endif
#endif // _WIN32

#if defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN)
#if TARGET_OS_MAC
#include <Security/Security.h>                  // 主打钥匙串管理、证书操作、加密安全
#endif
#endif // CPPHTTPLIB_USE_NON_BLOCKING_GETADDRINFO

#include <openssl/err.h>      // OpenSSL 错误处理核心头文件
#include <openssl/evp.h>      // OpenSSL 高级加密接口头文件,封装对称 / 非对称加密、哈希、签名等算法
#include <openssl/ssl.h>      // OpenSSL SSL/TLS 协议核心头文件,定义 SSL 上下文、连接、证书验证等函数
#include <openssl/x509v3.h>   // X.509 v3 证书扩展处理头文件,解析 / 生成证书扩展字段

#if defined(_WIN32) && defined(OPENSSL_USE_APPLINK)
#include <openssl/applink.c>  // 解决 Windows 平台下 OpenSSL 与 C/C++ 运行时库的链接冲突
#endif

#include <iostream>
#include <sstream>

#if defined(OPENSSL_IS_BORINGSSL) || defined(LIBRESSL_VERSION_NUMBER)
#if OPENSSL_VERSION_NUMBER < 0x1010107f
#error Please use OpenSSL or a current version of BoringSSL
#endif
#define SSL_get1_peer_certificate SSL_get_peer_certificate
#elif OPENSSL_VERSION_NUMBER < 0x30000000L
#error Sorry, OpenSSL versions prior to 3.0.0 are not supported
#endif

#endif // CPPHTTPLIB_OPENSSL_SUPPORT

// cpp-httplib 库针对 mbedTLS 加密库的跨平台条件编译逻辑
#ifdef CPPHTTPLIB_MBEDTLS_SUPPORT
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#include <mbedtls/error.h>
#include <mbedtls/md5.h>
#include <mbedtls/net_sockets.h>
#include <mbedtls/oid.h>
#include <mbedtls/pk.h>
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
#include <mbedtls/sha512.h>
#include <mbedtls/ssl.h>
#include <mbedtls/x509_crt.h>
#ifdef _WIN32
#include <wincrypt.h>
#ifdef _MSC_VER
#pragma comment(lib, "crypt32.lib")
#endif
#endif // _WIN32
#if defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN)
#if TARGET_OS_MAC
#include <Security/Security.h>
#endif
#endif // CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN

// Mbed TLS 3.x API compatibility
#if MBEDTLS_VERSION_MAJOR >= 3
#define CPPHTTPLIB_MBEDTLS_V3
#endif

#endif // CPPHTTPLIB_MBEDTLS_SUPPORT

// Define CPPHTTPLIB_SSL_ENABLED if any SSL backend is available
// This simplifies conditional compilation when adding new backends (e.g.,
// wolfSSL)
#if defined(CPPHTTPLIB_OPENSSL_SUPPORT) || defined(CPPHTTPLIB_MBEDTLS_SUPPORT)
#define CPPHTTPLIB_SSL_ENABLED
#endif

#ifdef CPPHTTPLIB_ZLIB_SUPPORT
#include <zlib.h>   // 提供轻量级、跨平台的 DEFLATE 算法压缩 / 解压缩接口
#endif

#ifdef CPPHTTPLIB_BROTLI_SUPPORT
#include <brotli/decode.h>    // 实现 Brotli 高压缩率算法的编码 / 解码,是 zlib/gzip 的升级版
#include <brotli/encode.h>
#endif

#ifdef CPPHTTPLIB_ZSTD_SUPPORT
#include <zstd.h>            // 实现 Zstd 算法的高性能压缩 / 解压缩,兼顾压缩率和速度
#endif

        按宏开关按需加载 SSL(OpenSSL/mbedTLS)、压缩(zlib/Brotli/Zstd)功能的头文件;适配 Windows/macOS 等系统的平台差异,解决编译冲突;校验加密库版本,定义兼容宏,保证不同环境下代码的可编译性

        这段代码是 cpp-httplib 实现 “跨平台、可插拔式功能扩展” 的基础,让库能根据用户的编译选项,适配不同系统和第三方库(加密 / 压缩)。需要用到这部分代码中的某些头文件时,我们只需要定义相应的宏。

四.总结

        httplib的头文件部分阅读完毕,httplib库源码具体用到头文件里的东西时再做具体讲解。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐