iOS Network Framework如何同时接收UDP单播与多播数据
问题根因
你现在的冲突来源于两个独立的Network对象(NWListener和NWMulticastGroup)同时尝试绑定3610端口,默认情况下系统不允许两个socket绑定同一个端口,先启动的NWMulticastGroup占用了端口,后续的NWListener无法正常绑定监听,所以单播数据无法接收。
最优解决方案:仅用NWMulticastGroup同时处理单播+多播
你初始化NWMulticastGroup时已经设置了disableUnicast: false,这个配置本身就支持NWMulticastGroup同时接收两类数据:
- 发往224.0.23.0:3610的多播数据
- 发往本地网卡IP:3610的单播数据
不需要额外启动NWListener监听单播,直接在多播的接收回调里区分数据类型处理即可。
修改后参考代码
import Foundation import Network class Controller: ObservableObject { @Published var rxContents = String() @Published var rxFrom = String() init() { receiveUdp() } func receiveUdp() { guard let multicast = try? NWMulticastGroup(for: [ .hostPort(host: "224.0.23.0", port: 3610) ], disableUnicast: false) else { fatalError() } let group = NWConnectionGroup(with: multicast, using: .udp) group.setReceiveHandler(maximumMessageSize: 16384, rejectOversizedMessages: true) { (message, content, isComplete) in guard let content = content, let msgStr = String(data: content, encoding: .utf8) else { return } let remoteEndpoint = message.remoteEndpoint print("收到数据来自: \(String(describing: remoteEndpoint)),内容: \(msgStr)") // 区分多播/单播数据 if case .hostPort(let host, _) = remoteEndpoint { if host.debugDescription == "224.0.23.0" { // 处理多播数据逻辑 print("这是多播数据") } else { // 处理单播数据逻辑 self.rxFrom = String(describing: remoteEndpoint) self.rxContents = msgStr print("这是单播数据") } } } group.stateUpdateHandler = { (newState) in print("Group entered state \(String(describing: newState))") } group.start(queue: .main) } }
备选方案:开启端口复用同时保留两个实例
如果确实需要分开处理单播和多播逻辑,可以给两个对象都配置端口复用参数,允许同一端口被多个socket绑定:
// 配置UDP参数开启端口复用 let udpParams = NWParameters.udp udpParams.allowLocalAddressReuse = true udpParams.allowPortReuse = true // 初始化NWListener时用自定义参数 guard let listener = try? NWListener(using: udpParams, on: 3610) else { fatalError() } // 初始化NWMulticastGroup时也用自定义参数 guard let multicast = try? NWMulticastGroup(for: [ .hostPort(host: "224.0.23.0", port: 3610) ], disableUnicast: false, parameters: udpParams) else { fatalError() }
注意事项
- 需要在项目中添加
com.apple.developer.networking.multicast权限声明,否则多播数据会被系统拦截 - iOS 14及以上版本需要主动申请本地网络权限,用户同意后才能正常收发局域网UDP数据
- NWMulticastGroup的
disableUnicast参数最低支持iOS 14、macOS 11系统
内容的提问来源于stack exchange,提问作者Hiro Fujita
相关产品推荐
相关产品推荐

