0

GCDAsyncUDPSocket を使用して、UDP 経由でネットワーク上の複数のハードウェア デバイスと通信する Swift デスクトップ アプリケーションを構築しています。最初のスキャンでは、ソケットを作成し、ブロードキャスト メッセージを送信して応答をリッスンします。デバイスから応答を受け取ると、すべての追加通信のために、そのデバイス用に一意の非ブロードキャスト ソケットが作成されます。

有線イーサネットを使用する場合、これはほぼ完全に機能します。ただし、WiFi を経由すると、Wireshark に一定の ARP 要求が戻ってくることがわかります。その多くは、メッセージを受信するはずのインターフェイスの間違った MAC アドレスで応答されています。

私は 2 日間、ARP の問題に対する実証済みの真の解決策を探していましたが、運がありませんでした。

toHost の代わりに sendData toAddress を使用すると MAC アドレスが含まれることが GCDAsync のドキュメントでわかりますが、これを試すためにインターフェイスの詳細を使用してアドレス NSData オブジェクトを作成する方法を整理することができませんでした。 ARPの問題を解決します。

私のブロードキャストソケットの現在のコードは次のとおりです。

class BroadcastNetworkSocket: NSObject, GCDAsyncUdpSocketDelegate{
var socket:GCDAsyncUdpSocket!
let broadcastIP = "255.255.255.255"
let broadcastPort:UInt16 = 22202
let PORT:UInt16 = 0

override init (){
    super.init()
}

init(whichInterface: String){
    super.init()
    setupConnection(whichInterface)
}

func setupConnection(whichInterface: String){
    var error : NSError?
    socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
    socket.setPreferIPv4()
    socket.enableBroadcast(true, error: &error)
    socket.beginReceiving(&error)

}

func send(message:String, toAddress:String, toPort:UInt16){
    let data = message.dataUsingEncoding(NSUTF8StringEncoding)
    socket!.sendData(data, toHost: toAddress, port: toPort, withTimeout: 2, tag: 0)
}

func sendNetworkScan(){       
    let message = "!??#"
    let data = message.dataUsingEncoding(NSUTF8StringEncoding)
    socket!.sendData(data, toHost: broadcastIP, port: broadcastPort, withTimeout: 2, tag: 0)
    println("outgoing message: \(message)");
}

func closeSocket(){
    socket!.close()
}

func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!,      withFilterContext filterContext: AnyObject!) {
    let theMessage = NSString(data: data, encoding: NSUTF8StringEncoding)

    var host: NSString?
    var port1: UInt16 = 0
    GCDAsyncUdpSocket.getHost(&host, port: &port1, fromAddress: address)


    println("incoming message: \(theMessage!)")
    println("incoming address: \(host!)")
    NSNotificationCenter.defaultCenter().postNotificationName(broadcastNetworkMessageReceivedNotificationKey, object: self, userInfo: ["message":theMessage!, "incomingIP":host!])

}


func verifyIPAddress(incomingText: String)-> Bool{

    let validIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"


    if incomingText.rangeOfString(validIpAddressRegex, options: .RegularExpressionSearch) != nil{
        return true
    }

    else {
        return false
    }   
}
}
4

0 に答える 0