简体   繁体   English

GCDAsyncUDPSocket:无法使IPv6上的UDP多播正常工作

[英]GCDAsyncUDPSocket: cannot get UDP multicast over IPv6 to work

I cannot get UDP multicast over IPv6 to work. 我无法通过IPv6获得UDP多播工作。 The platform on which I'm trying to do this is iOS (using Swift). 我正在尝试执行此操作的平台是iOS(使用Swift)。 I have a GCDAsyncUdpSocket and configure it like this: 我有一个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)")
}

After that, I try to send some data to a multicast address: 之后,我尝试将一些数据发送到多播地址:

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

At that point, when stepping through the GCDAsyncUDPSocket code, I end up in a call to sendto in the method doSend (line 3919). 那时,逐步执行GCDAsyncUDPSocket代码时,我最终在doSend方法(第3919行)中调用sendto This call returns -1 and the error is "no route to host". 该调用返回-1,错误是“没有路由到主机”。 I'm running this in the iOS simulator. 我正在iOS模拟器中运行它。 When I enumerate all available network interfaces, I get this: 当我枚举所有可用的网络接口时,得到以下信息:

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

Any help is much appreciated! 任何帮助深表感谢!

I have solved my issue, I succeeded in doing a send/receive over IPv6 UDP Multicast. 我已经解决了我的问题,成功完成了通过IPv6 UDP多播的发送/接收。 The problem turned out to be a combination of issues. 问题原来是问题的组合。

  • For sending these messages, it is required to set the socket option IPV6_MULTICAST_IF , which GCDAsyncUdpSocket does not do. 为了发送这些消息,需要设置套接字选项IPV6_MULTICAST_IFGCDAsyncUdpSocket不这样做。 (Receiving doesn't seem to require it.) (接收似乎不是必需的。)
  • When sending a message, you do have to bind before you can send (but don't bind to a specific port, because what you're binding is the source port, not the destination port). 发送消息时,必须先绑定才能发送消息(但不要绑定到特定端口,因为要绑定的是源端口,而不是目标端口)。
  • When you try to set a Swift object as a delegate of an Objective-C object, make sure your Swift object inherits from NSObject , or be screwed! 当您尝试将Swift对象设置为Objective-C对象的委托时,请确保您的Swift对象继承自NSObject ,或者被搞砸了! No warnings, no errors, the delegate simply doesn't get called. 没有警告,没有错误,仅不会调用该委托。
  • Wireshark was my friend again :). Wireshark再次成为我的朋友:)。 I could see that the socket started listening because of the ICMPv6 "Multicast Listener Report v2" coming by, with contents: "Multicast Address Record Changed to exclude: ff12::5222". 由于ICMPv6“多播侦听器报告v2”的到来,我可以看到套接字开始侦听,其内容为:“多播地址记录已更改为排除:ff12 :: 5222”。 Note that "exclude" means that it does not get filtered away, in other words: that it is passed on. 请注意,“排除”意味着它不会被过滤掉,换句话说:它会继续传递。 (Thanks Paul!) (谢谢保罗!)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM