一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Swoole中IPV4与IPV6配置的差别

时间:2026-07-21 09:38:48 编辑:袖梨 来源:一聚教程网

Swoole中host参数显式控制协议栈:0.0.0.0仅IPv4,::仅IPv6(默认支持IPv4映射需bindv6only=0),双栈需addlistener两次;不自动兼容,无内置dual-stack单socket模式。

直接结论:Swoole 启动 TCP/HTTP 服务器时,host 参数决定监听协议栈,IPv4 和 IPv6 不是“同时启用”或“自动兼容”的选项,而是由绑定地址显式控制;默认 0.0.0.0 只监听 IPv4,:: 才监听 IPv6,混用需额外处理。

listen host 参数必须显式指定 IPv4 或 IPv6 地址

Swoole 的 Server->addlistener() 或构造函数中 host 字段不支持模糊值(如 "localhost" 或空字符串),也不自动 fallback。它直接传给底层 bind() 系统调用,因此:

  • host => "0.0.0.0":仅绑定 IPv4 ANY,**不会**接受 IPv6 连接,即使系统开启 IPv6 且双栈开启
  • host => "::":绑定 IPv6 ANY,可接受 IPv4 映射地址(如 ::ffff:192.168.1.100),但前提是内核启用 net.ipv6.bindv6only = 0(默认多数 Linux 发行版为 0)
  • host => "127.0.0.1"host => "::1" 是严格分离的:前者只响应 IPv4 回环,后者只响应 IPv6 回环

想同时监听 IPv4 和 IPv6,得手动 addlistener 两次

Swoole 没有内置 “dual-stack” 单 socket 监听模式(即一个 socket 同时处理 IPv4/IPv6)。常见错误是以为设 host => "::" 就能“通吃”,结果发现 IPv4 客户端连不上——尤其在容器或某些云主机上,bindv6only 被设为 1,:: 就真的只收 IPv6。

正确做法是显式添加两个监听器:

$server = new SwooleHttpServer("::", 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP6);$server->addlistener("0.0.0.0", 9501, SWOOLE_SOCK_TCP); // 注意:端口必须相同
  • 第一个监听器用 SWOOLE_SOCK_TCP6 + "::",处理 IPv6 流量
  • 第二个用 SWOOLE_SOCK_TCP + "0.0.0.0",处理 IPv4 流量
  • 两个监听器共享同一 port,Swoole 内部会分别管理 fd,但业务逻辑共用同一个 onRequest 回调

客户端获取真实 IP 时,remote_ip 字段行为不同

当使用双监听时,$request->server['remote_addr'] 返回的 IP 字符串格式取决于连接走的是哪个 socket:

  • IPv4 连接:返回点分十进制,如 "192.168.1.100"
  • IPv6 连接:返回冒号十六进制格式,可能含压缩,如 "2001:db8::1" 或完整形式 "2001:0db8:0000:0000:0000:0000:0000:0001"
  • 若启用了 IPv4-mapped IPv6 地址(::ffff:192.168.1.100),Swoole 默认**不自动转换**为 IPv4 格式,remote_addr 就是那个映射地址字符串

需要做兼容判断时,别依赖字符串前缀,用 PHP 原生函数更可靠:

if (filter_var($request->server['remote_addr'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {    // IPv4} elseif (filter_var($request->server['remote_addr'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {    // IPv6}

SSL/TLS 配置下 IPv6 监听需注意证书 SAN

如果用 ssl 选项启动 HTTPS 服务并监听 "::",客户端通过 IPv6 访问时,TLS 握手仍依赖证书中的 Subject Alternative Name(SAN)。常见坑:

  • 证书只含 DNS:example.com,没加 IP:2001:db8::1 —— IPv6 直连会触发证书域名不匹配警告
  • Let’s Encrypt 等 ACME 服务商**不签纯 IP 的 SSL 证书**(除私有 CA 外),所以生产环境几乎从不给 IPv6 地址单独配证书
  • 实际部署中,应让 DNS 同时解析 A 和 AAAA 记录,客户端通过域名访问,由证书的 DNS SAN 覆盖,而不是靠 IP 直连

换句话说:HTTPS + IPv6 的正确姿势是「用域名访问」,不是「用 IPv6 地址直连」;监听 "::" 只是网络层支持,应用层信任链仍走 DNS。

热门栏目