TCP、UDP、RUDP、HTTP/HTTPS、WebSocket/WSS 和 TLS 通过同一套 start(host, port)
接口接收 IPv4、IPv6 地址。UDP cast 也支持 IPv6 端点。
| 用途 | IPv4 | IPv6 |
|---|---|---|
| 回环监听/连接 | 127.0.0.1 |
::1 |
| 监听所有接口 | 0.0.0.0 |
:: |
| HTTP Host/WebSocket authority | 127.0.0.1:8080 |
[::1]:8080 |
| URL | http://127.0.0.1:8080/ |
http://[::1]:8080/ |
传给 start 的 IPv6 地址不加方括号,端口用单独参数传入。
HTTP 请求自行设置 Host;WebSocket 客户端构造握手地址。
域名可能解析到任一种地址族,localhost 不保证使用 IPv6。
域名与地址解析
域名传给 host,端口用单独参数传入:
arknet::tcp_client client;
if (!client.start("example.com", 9000))
std::cerr << arknet::last_error_msg() << '\n';HTTP 客户端可以省略端口:http_client.start("example.com") 默认使用 80,
https_client.start("example.com") 默认使用 443,异步接口 async_start(host)
遵循相同规则。http_request.async_request(host, request, completion) 默认使用 80。
显式端口优先;TCP、UDP、RUDP 等通用端点仍需指定端口。
具体示例见 HTTP 客户端。
客户端使用 Asio 异步 resolver,遵循操作系统的名称解析配置,包括 DNS 和
hosts 文件。解析结果可以包含 IPv4 或 IPv6 地址。基于 TCP 的客户端在 socket
连接失败后,按解析器返回的顺序尝试其他地址,未实现 IPv4/IPv6 并行连接的
Happy Eyeballs 策略。UDP 的 connect 只设置对端地址,不验证对端是否可达;
UDP 和 RUDP 不会根据对端可达性自动切换地址。
Asio 的 endpoint 保存 IP 地址和端口,不能保存域名。
arknet::to_endpoint<asio::ip::tcp::endpoint>(host, port) 同步解析并返回第一个地址,
使用前检查 arknet::get_last_error()。
UDP cast 的 async_send(host, port, data) 异步解析,并选取第一个与 socket
的 IPv4/IPv6 地址族一致的地址。
HTTPS 和 WSS 保留域名用于 TLS SNI 和证书身份校验。除非证书包含对应 IP 身份,否则不要用解析后的 IP 替代域名。连接建立后保持当前对端地址,重连时 重新解析。arknet 尚未提供选择自定义 DNS 服务器的 API。
客户端与服务端
完整的 IPv6 回显示例
在 ::1 上启动两端,检查回复后停止。构建并运行:
cmake --build build --target arknet_ipv6_echo
build/examples/arknet_ipv6_echoTCP、UDP、
WebSocket 和 HTTP 的客户端、服务端示例
可将两端回环地址改为 ::1。HTTP 请求使用:
request.set(arknet::http::field::host, "[::1]:8080");TLS 客户端将 IP 地址与证书的 IP subject alternative name 校验,包括完整的 IPv6
地址。只有 localhost 或 127.0.0.1 身份的证书不能验证 ::1。
身份配置见 TLS 用法。独立的 tests/certs/ipv6 证书仅用于测试。
监听策略
绑定 :: 会监听全部 IPv6 接口。是否接收 IPv4 映射连接取决于平台的
IPV6_V6ONLY 策略,单独绑定 :: 不保证双栈服务。
需要明确支持两种地址族时,可分别监听 0.0.0.0 和 ::,并将 IPv6 socket
设为只接收 IPv6。在 socket 打开后、绑定前,通过 bind_init 设置选项:
server.bind_init([&]
{
arknet::error_code error;
server.acceptor().set_option(asio::ip::v6_only(true), error);
if (error) throw arknet::system_error(error);
});应用需要接受外部流量时才监听外部接口。UDP 多播配置区分地址族,IPv6 没有 IPv4 广播的等价功能。链路本地 IPv6 地址还需要指定接口作用域。
测试与基准
独立 doctest 程序为 build/tests/arknet_ipv6_test。
两个 C++ 基准和 shell 批量工具均支持 --address-family ipv6:
build/benchmarks/arknet_loopback_benchmark --protocol udp --address-family ipv6 \
--payload 1024 --clients 16 --window 1 --io-model shared --io-threads 1 \
--seconds 1 --warmup 0.25
build/benchmarks/arknet_loopback_benchmark --protocol https --address-family ipv6 \
--certs tests/certs/ipv6 --payload 1024 --clients 16 --window 1 \
--io-model shared --io-threads 1 --seconds 1 --warmup 0.25
build/benchmarks/arknet_coroutine_benchmark --protocol tcp --execution coroutine \
--address-family ipv6 --payload 1024 --clients 16 --window 16 \
--io-model shared --io-threads 4 --seconds 1 --warmup 0.25现有性能矩阵使用 IPv4 回环。::1 验证不代表跨主机吞吐量、IPv4/IPv6 性能一致、
多播可用性或所有平台的双栈行为。