chakokuのブログ(rev4)

日々のごった煮ブログです

Swift Network Frameworkを使ってUDP Multicast通信を試す

iOSアプリ開発に向けて、Network Frameworkを使ってUDP Multicast通信をやってみる。細かい所はまだわかっていないけど、以下のコードで、WindowsでMulticastした電文の送受信までは動いた*1

import Network

guard let multicast = try? NWMulticastGroup(for:
    [ .hostPort(host: "224.0.23.0", port: 3610) ])
    else { fatalError("error in Muticast") }

let group = NWConnectionGroup(with: multicast, using: .udp)

group.setReceiveHandler(maximumMessageSize: 1024, rejectOversizedMessages: true) { (message, content, isComplete) in
    print("Received message from \(String(describing: message.remoteEndpoint))")

    //let sendContent = Data("ack".utf8)
    //message.reply(content: sendContent)
}
group.stateUpdateHandler = { (newState) in
    print("Group entered state \(String(describing: newState))")
}
let queue = DispatchQueue(label: "ExampleNetwork")
group.start(queue: queue)
//group.start(queue: .main)
sleep(10)

let str = "helloAll"
let groupSendContent = str.data(using: .utf8)
group.send(content: groupSendContent) { (error)  in
    print("Send complete with error \(String(describing: error))")
}
group.cancel()
print("bye")

実行結果の表示

Group entered state waiting(POSIXErrorCode: Network is down)
Group entered state ready                                                   // ・・状態がReadyに遷移
Received message from Optional(192.168.10.155:62725)   // ・・・送信しているWindows側IP
Received message from Optional(192.168.10.155:62726)
Send complete with error nil
Received message from Optional(192.168.10.161:50947)   // ・・・Multicastした自分自身のIP
Received message from Optional(192.168.10.155:62727)
bye
Group entered state cancelled                                            // ・・状態がCancelledに遷移

ネットワークの状態がReadyに遷移したタイミングでUDPマルチキャストを投げるように修正
受信データを表示させたいが、型変換がよくわからずWarningになっている。
Swiftの基本仕様がわかっていない。。

import Network

guard let multicast = try? NWMulticastGroup(for:
    [ .hostPort(host: "224.0.23.0", port: 3610) ])
    else { fatalError("error in Muticast") }

let group = NWConnectionGroup(with: multicast, using: .udp)

group.setReceiveHandler(maximumMessageSize: 1024, rejectOversizedMessages: true) { (message, content, isComplete) in
    print("Received message from \(String(describing: message.remoteEndpoint))")
    //let message = String(data: content, encoding: .utf8)
    //let message = Data(content, encoding: .utf8)
    print(content)
    //let sendContent = Data("ack".utf8)
    //message.reply(content: sendContent)
}
group.stateUpdateHandler = { (newState) in
    print("Group entered state \(String(describing: newState))")
    switch newState {
    case .ready:
        print("ready")
        let str = "helloAll"
        let groupSendContent = str.data(using: .utf8)
        group.send(content: groupSendContent) { (error)  in
            print("Send complete with error \(String(describing: error))")
        }
    case .waiting(let error):
        print("waiting")
        print(error)
    case .setup:
        print("setup")
    case .cancelled:
        print("cancelled")
    case .failed:
        print("failed")
    //case .preparing:
    //    print("preparing")
    default:
        print("default")
    }
}
let queue = DispatchQueue(label: "ExampleNetwork")
group.start(queue: queue)
//group.start(queue: .main)
sleep(5)
group.cancel()
print("bye")

■参考にした記事
Swiftでコマンドラインツール作成の誘い - Qiita

*1:受信データの内容は未確認