0

我无法让 IPv6 上的 UDP 多播工作。我正在尝试执行此操作的平台是 iOS(使用 Swift)。我有一个GCDAsyncUdpSocket并像这样配置它:

self.socket!.setIPv4Enabled(false)
self.socket!.setIPv6Enabled(true)
do {
    try self.socket!.bindToPort(Announcement.ipv6BroadcastPort, interface: "en0")
}
catch let error {
    print("bind failed: \(error)")
    throw error
}
do {
    try self.socket!.joinMulticastGroup("ff32::5222", onInterface: "en0")
}
catch let e {
    print("join multicast failed: \(e)")
}

之后,我尝试将一些数据发送到多播地址:

socket.sendData(data, toHost:"ff32::5222", port: 21026, withTimeout: 5, tag: 0)

那时,当单步执行 GCDAsyncUDPSocket 代码时,我最终调用sendto了方法doSend(第 3919 行)。此调用返回 -1,错误是“没有到主机的路由”。我在 iOS 模拟器中运行它。当我枚举所有可用的网络接口时,我得到了这个:

Name: lo0
Address: Optional("::1ebc:680b:100:0")
Family: NetUtils.Interface.Family.ipv6
Supports multicast: true

Name: lo0
Address: Optional("::2bc:680b:100:0")
Family: NetUtils.Interface.Family.ipv4
Supports multicast: true

Name: lo0
Address: Optional("fe80::1ebc:680b:100:0")
Family: NetUtils.Interface.Family.ipv6
Supports multicast: true

Name: en0
Address: Optional("fe80::1ebc:680b:100:0")
Family: NetUtils.Interface.Family.ipv6
Supports multicast: true

Name: en0
Address: Optional("2001:984:3427:1:1ebc:680b:100::")
Family: NetUtils.Interface.Family.ipv6
Supports multicast: true

Name: en0
Address: Optional("2001:984:3427:1:1ebc:680b:100::")
Family: NetUtils.Interface.Family.ipv6
Supports multicast: true

Name: en0
Address: Optional("::2bc:680b:100:0")
Family: NetUtils.Interface.Family.ipv4
Supports multicast: true

Name: awdl0
Address: Optional("fe80::1ebc:680b:100:0")
Family: NetUtils.Interface.Family.ipv6
Supports multicast: true

Name: utun0
Address: Optional("fe80::1ebc:680b:100:0")
Family: NetUtils.Interface.Family.ipv6
Supports multicast: true

Name: utun0
Address: Optional("fde6:4b33:67e4:9d5e:1ebc:680b:100::")
Family: NetUtils.Interface.Family.ipv6
Supports multicast: true

任何帮助深表感谢!

4

1 回答 1

2

我已经解决了我的问题,我成功地通过 IPv6 UDP 多播进行了发送/接收。这个问题原来是多个问题的组合。

  • 要发送这些消息,需要设置套接字选项IPV6_MULTICAST_IFGCDAsyncUdpSocket但不这样做。(接收似乎不需要它。)
  • 发送消息时,您必须先绑定才能发送(但不要绑定到特定端口,因为您要绑定的是源端口,而不是目标端口)。
  • 当您尝试将 Swift 对象设置为 Objective-C 对象的委托时,请确保您的 Swift 对象继承自NSObject,否则会被搞砸!没有警告,没有错误,委托根本不会被调用。
  • Wireshark 再次成为我的朋友 :)。我可以看到套接字开始侦听是因为 ICMPv6“多播侦听器报告 v2”的内容:“多播地址记录已更改为排除:ff12::5222”。请注意,“排除”意味着它不会被过滤掉,换句话说:它会被传递。(谢谢保罗!)

这里的概念工作证明:https ://source.ind.ie/project/pulse-swift/blob/28bd0f48e3d4fa99f6095321a89036863c3f7a83/pulse-swift/discovery/Greeter.swift

于 2015-08-11T22:16:49.957 回答