GCDAsyncUDPSocket:无法通过IPv6获得UDP多播功能

时间:2015-07-22 21:24:14

标签: ios swift ipv6 multicast cocoaasyncsocket

我无法通过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(第3919行)中调用doSend。此调用返回-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

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

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

  • 要发送这些消息,需要设置IPV6_MULTICAST_IF不执行的套接字选项GCDAsyncUdpSocket。 (接收似乎不需要它。)
  • 发送邮件时,您必须先绑定才能发送(但不要绑定到特定端口,因为您绑定的是源端口,而不是目标端口)。
  • 当您尝试将Swift对象设置为Objective-C对象的委托时,请确保您的Swift对象继承自NSObject,或者被搞砸!没有警告,没有错误,委托根本就没有被调用。
  • Wireshark再次成为我的朋友:)。我可以看到套接字因为ICMPv6“Multicast Listener Report v2”而开始监听,内容为:“Multicast Address Record Changed to exclude:ff12 :: 5222”。请注意,“排除”意味着它不会被过滤掉,换句话说:它被传递。 (谢谢保罗!)

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