用Swift实现UDP“监听器”?

时间:2022-07-25 20:04:24

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. The answer explained that I've implementing the send portion of the UDP broadcast, but I've not implemented anything to "listen" for responses. And that's where I'm struggling. Here's my send code;

我一直在尝试逆向设计一个项目,在我的网络上发现Logitech Harmony Hub设备,并发布了这个问题,看看是否有人能帮助我理解UDP广播。答案解释说我已经实现了UDP广播的发送部分,但是我还没有实现任何“监听”响应。这就是我挣扎的地方。这是我发送的代码;

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?
  • 我知道我需要调用beginreceive(),我可以在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. I was able to read the response in didReadData.

我还将此控制器设置为GCDAsyncSocketDelegate,这似乎很管用。我能从di无畏号的数据中读出反应。

1 个解决方案

#1


2  

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 hub似乎没有发送任何东西,所以我不确定正在发送的数据是否正确。

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

#1


2  

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 hub似乎没有发送任何东西,所以我不确定正在发送的数据是否正确。

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