简体   繁体   English

在Swift中实现UDP“监听器”?

[英]Implementing A UDP “Listener” In Swift?

I've been trying to somewhat reverse engineer a project to discover Logitech Harmony Hub devices on my network, and posted this question to see if someone could help me understand UDP broadcast. 我一直在尝试对项目进行反向工程,以发现网络上的Logitech Harmony Hub设备,并发布了问题,以查看是否有人可以帮助我理解UDP广播。 The answer explained that I've implementing the send portion of the UDP broadcast, but I've not implemented anything to "listen" for responses. 答案说明我已经实现了UDP广播的发送部分,但是还没有实现“监听”响应的任何功能。 And that's where I'm struggling. 那就是我努力的地方。 Here's my send 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)

    }

}

I see I have the code to handle the response (in didReceiveData ), but I'm unsure what I need to implement to get the listening going; 我看到我有处理响应的代码(在didReceiveData ),但是我不确定我需要实现什么才能使监听继续。

  • Do I need to "bind" to the listener port (in this case, 61991)? 我是否需要“绑定”到侦听器端口(在这种情况下为61991)?
  • Do I need to "join the multicast group"? 我需要“加入多播组”吗? And if so, at what address? 如果是这样,在什么地址? I tried doing so at "255.255.255.255", which creates a setSocketOpt() error when I build. 我尝试在“ 255.255.255.255”处执行此操作,这在我构建时会产生setSocketOpt()错误。
  • I know I need to call beginReceiving() , and can I do all this on socket , or do I need to instantiate a separate socket for the listening? 我知道我需要调用beginReceiving() ,并且可以在socket上完成所有这些操作,还是需要实例化一个单独的socket进行监听?

Edit: Resolved 编辑:已解决

The below answer absolutely helped me to solve the problem. 以下答案绝对可以帮助我解决问题。 It seemed I wasn't getting a response because I had not fully implemented a means of handling the incoming response. 似乎我没有收到响应,因为我没有完全实现一种处理传入响应的方法。

Per the code provided in the answer below, I added the following; 根据下面答案中提供的代码,我添加了以下内容;

// 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)
    }

I also set this controller to be a GCDAsyncSocketDelegate , which seemed to do the trick. 我还将此控制器设置为GCDAsyncSocketDelegate ,这似乎可以解决问题。 I was able to read the response in didReadData . 我能够在didReadData读取响应。

The following code changes enabled me to receive UDP packets that I sent from my Mac using netcat, but my Harmony hub didn't seem to send anything, so I am not sure if the data that is being sent is correct. 以下代码更改使我能够接收使用netcat从Mac发送的UDP数据包,但是Harmony集线器似乎没有发送任何内容,因此我不确定所发送的数据是否正确。

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)
    }

}

From the command line you can test receiving using the command 在命令行中,您可以使用以下命令测试接收

echo -n "hello" | nc -4u -w1 x.x.x.x 61991

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

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