Die Implementierung Eines UDP – „Listener“ In Swift?

Ich habe versucht, etwas reverse-Engineering eines Projektes zu entdecken Logitech-Harmony-Hub-Geräte in meinem Netzwerk, und gepostet diese Frage zu sehen, wenn jemand könnte mir helfen zu verstehen UDP-broadcast. Die Antwort erklärt, dass ich die Umsetzung der senden Teil der UDP-broadcast, aber ich habe nicht realisiert, etwas zu „hören“ für die Antworten. Und das ist, wo ich zu kämpfen. Hier ist meine senden code;

import UIKit
import CocoaAsyncSocket

class ViewController: UIViewController, GCDAsyncUdpSocketDelegate {

var address = "255.255.255.255"
var port:UInt16 = 5224
var socket:GCDAsyncUdpSocket!
var socketReceive:GCDAsyncUdpSocket!
var error : NSError?

override func viewDidLoad() {
super.viewDidLoad()

let message = "_logitech-reverse-bonjour._tcp.local.\n61991".dataUsingEncoding(NSUTF8StringEncoding)

socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
socket.sendData(message, toHost: address, port: port, withTimeout: 1000, tag: 0)

    do {
        try socket.enableBroadcast(true)
    } catch {
        print(error)
    }

}

func udpSocket(sock: GCDAsyncUdpSocket!, didConnectToAddress address: NSData!) {
    print("didConnectToAddress");
}

func udpSocket(sock: GCDAsyncUdpSocket!, didNotConnect error: NSError!) {
    print("didNotConnect \(error)")
}

func udpSocket(sock: GCDAsyncUdpSocket!, didSendDataWithTag tag: Int) {
    print("didSendDataWithTag")
} 

func udpSocket(sock: GCDAsyncUdpSocket!, didNotSendDataWithTag tag: Int, dueToError error: NSError!) {
    print("didNotSendDataWithTag")
}

func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) {

var host: NSString?
var port1: UInt16 = 0
GCDAsyncUdpSocket.getHost(&host, port: &port1, fromAddress: address)
print("From \(host!)")

let gotdata: NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
print(gotdata)

    }

}

Ich sehe, ich habe der code zum verarbeiten der Antwort (in didReceiveData), aber ich bin mir nicht sicher, was ich implementieren müssen, um das hören gehen;

  • Muss ich auf „verbinden“, um den listener-port (in diesem Fall, 61991)?
  • Muss ich „der multicast-Gruppe beitreten“? Und wenn ja, an welche Adresse? Ich habe versucht, so auf „255.255.255.255“, das schafft eine setSocketOpt() Fehler, wenn ich Baue.
  • Ich weiß, ich brauche zu nennen beginReceiving(), und kann ich dies alles auf socket oder muss ich zu instanziieren, die eine separate Buchse für das hören?

Edit: Gelöst

Die unter Antwort, die absolut geholfen, mich um das problem zu lösen. Es schien, ich war nicht immer eine Antwort, weil ich noch nicht voll implementiert einen Umgang mit der eingehende Antwort.

Pro den code in der Antwort unten habe ich noch folgende;

//Setup the other socket (used to handle the response from the Harmony hub)
    otherSocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())

    do {

        //Accept connections on port 61991
        try otherSocket.acceptOnPort(61991)

    } catch {

        //Handle any errors here
        print(error)
    }

Ich auch dieses Controllers ein GCDAsyncSocketDelegate, die schien, den trick zu tun. Ich war in der Lage, die Antwort Lesen, in didReadData.

InformationsquelleAutor ZbadhabitZ | 2016-02-13



One Reply
  1. 3

    Die folgenden code-änderungen aktiviert, mich zu empfangen UDP-Pakete, die ich gesendet von meinem Mac mit Hilfe von von netcat, aber meine Harmony hub schien nicht zu senden, alles, so bin ich nicht sicher, ob die gesendeten Daten korrekt sind.

    override func viewDidLoad() {
    super.viewDidLoad()
    
    let message = "_logitech-reverse-bonjour._tcp.local.\n61991".dataUsingEncoding(NSUTF8StringEncoding)
    
    socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
    
    
        do {
            try self.socket.bindToPort(61991)
            try self.socket.beginReceiving()
            try socket.enableBroadcast(true)
            socket.sendData(message, toHost: address, port: port, withTimeout: 1000, tag: 0)
        } catch {
            print(error)
        }
    
    }

    Von der Befehlszeile aus können Sie testen, erhalten Sie mit dem Befehl

    echo -n "hello" | nc -4u -w1 x.x.x.x 61991
    • Hi @Paulw11 – Danke für die Klärung dieser. Mit deinem code, ich bin auch in der Lage Nachrichten zu empfangen, die per Terminal, und erhalten Sie auf dem bestimmten port in meiner app. Ich habe die gleiche Erfahrung mit meiner Harmony Hub. Als test habe ich try self.socket.bindToPort(5224) in meiner app, und verwendet die Harmony-app auf meinem iPhone/gleichen wifi-Netzwerk zu tun, finden Sie einen neuen hub. Er sandte eine Nachricht in form _logitech-reverse-bonjour._tcp.local.\nXXXXX, obwohl XXXXX variiert werden, um einen anderen Anschluss zu jeder Zeit.
    • Auch, @Paulw11 – ich bin eigentlich finden, dass die NODE.JS Projekt versuche ich auf Basis dieses Projekt ist jetzt nicht in der Lage zu finden, meine bereits etabliert Harmony Hub (es war in der Lage, Letzte Woche). Ich bin mir nicht sicher, die genauen Schritte, aber es ist fast so, als wenn mit der NODE.JS Projekt können Sie finden die Nabe einmal, und dann der hub reagiert nicht mehr auf UDP-broadcasts, bis es zurückgesetzt wird (ausgesteckt und wieder eingesteckt). Ich bin immer noch versuchen, es herauszufinden.
    • Folgenden, bis auf diese, jetzt weiß ich, dass die iOS-app ist nicht das empfangen der Antwort von dem Harmony Hub. Als test habe ich versucht zu kick-off der node.js Skript zu entdecken, die Harmonie Hubs auf einem anderen computer, und ich kann bestätigen, dass die Nachricht gesendet ist, was in diesem code verwendet. Allerdings sieht es so aus das node.js Projekt ist eigentlich instanzieren ist es einen eigenen server (in der responseCollector.js server), die für den Empfang der Antwort von der Harmonie; es ist nicht einfach, die port 61991, wenn das möglich ist.
    • Der code in dieser Antwort ist die gleiche wie die responseCollector.js der einzige Unterschied ist, dass die port-61991 hartkodiert ist, wie es ist hart codiert in Ihre ursprüngliche Ausstrahlung, während die responseCollector.js verwendet einen port, der angegeben ist, in eine variable. Ich bestätigt über das nc-Befehl, der die app hört auf diesen port.
    • Hi @Paulw11 – Sorry, war mir nicht klar. Was ich interessant finde, ist, dass, wenn ich eine Nachricht senden auf port 61991 (entweder über die iOS app oder mit nc-Befehl), die node.js Skript nicht abholen der Nachricht, obwohl es nicht konsequent abholen eine Antwort vom Harmony Hub zu jeder Zeit. Ich habe versucht, das senden der Nachricht an eine broadcast-Adresse, und direkt auf die IP des Rechners mit dem node.js Skript, aber ich kann es nicht erhalten, um es aufzuheben, wie es funktioniert mit der Harmony Hub Antwort. Fast wie der Harmony Hub Antwort oder die node.js Skript ist nicht nur einfach senden/empfangen auf 61991.
    • Die node.js code ist, der nicht eine Feste port-61991 wie das ihrige tut; Sie müssen wissen, über welchen port die node.js code sendet in der Nachricht und ist daher hören Sie auf und senden Sie dann zu diesem port.
    • Ich sehe. Ich habe seit der „discover.js“ Datei in der „Beispiele“ Ordner, die zu sein scheint, mit der port-61991 (das ist, wo ich den Hafen aus in den ersten Platz).
    • Ich habe es funktioniert. Die Bearbeitung meiner obigen Frage mit den code verwendet, um das Problem zu beheben. Ihre Unterstützung war unglaublich geschätzt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.