You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter/Dart UDP客户端如何同时适配IPv4与IPv6网络?

解决Dart RawDatagramSocket双栈(IPv4/IPv6)兼容问题

要让你的Datagram客户端在纯IPv4或纯IPv6网络中无需指定协议版本即可正常工作,核心是同时绑定IPv4和IPv6两个套接字——因为单个RawDatagramSocket实例只能处理一种协议版本的数据包。

实现步骤

  1. 分别创建IPv4和IPv6的套接字实例
  2. 统一监听两个套接字的读写事件
  3. 发送数据时根据目标服务器的地址版本选择对应套接字

代码示例

首先实现双栈套接字的创建和事件监听:

import 'dart:io';

class DualDatagramClient {
  static RawDatagramSocket? _ipv4Socket;
  static RawDatagramSocket? _ipv6Socket;

  static Future<void> init() async {
    // 绑定IPv4通配地址和端口
    _ipv4Socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 50943);
    // 绑定IPv6通配地址和端口
    _ipv6Socket = await RawDatagramSocket.bind(InternetAddress.anyIPv6, 50943);

    // 为两个套接字注册事件处理逻辑
    _setupSocketListener(_ipv4Socket!);
    _setupSocketListener(_ipv6Socket!);
  }

  static void _setupSocketListener(RawDatagramSocket socket) {
    socket.listen((event) {
      if (event == RawSocketEvent.read) {
        final datagram = socket.receive();
        if (datagram != null) {
          // 处理接收到的数据包
          print('Received from ${datagram.address}:${datagram.port} - ${String.fromCharCodes(datagram.data)}');
        }
      }
    });
  }

  // 根据服务器地址版本选择对应套接字发送数据
  static void send(InternetAddress serverAddr, int port, List<int> data) {
    if (serverAddr.type == InternetAddressType.IPv4) {
      _ipv4Socket?.send(data, serverAddr, port);
    } else if (serverAddr.type == InternetAddressType.IPv6) {
      _ipv6Socket?.send(data, serverAddr, port);
    }
  }
}

使用方式

void main() async {
  await DualDatagramClient.init();
  
  // 向IPv4服务器发送数据
  final ipv4Server = InternetAddress('192.168.1.100');
  DualDatagramClient.send(ipv4Server, 50943, 'Hello IPv4'.codeUnits);
  
  // 向IPv6服务器发送数据
  final ipv6Server = InternetAddress('fe80::1%en0');
  DualDatagramClient.send(ipv6Server, 50943, 'Hello IPv6'.codeUnits);
}

关键说明

  • 单个RawDatagramSocket只能绑定一种协议版本,无法同时处理IPv4和IPv6数据包,因此必须创建两个独立实例。
  • 部分系统中,IPv6套接字默认可以接收IPv4映射地址的数据包,但这种行为不具备跨平台一致性,同时绑定两个套接字是最可靠的方案。
  • 发送数据时通过InternetAddress.type判断目标地址版本,选择对应套接字发送,确保数据包能正确到达服务器。

内容的提问来源于stack exchange,提问作者Antte Heatta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:45:27