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

时间:2016-02-13 16:36:32

标签: ios swift udp cocoaasyncsocket

我一直试图对我的网络上的Logitech Harmony Hub设备进行一些反向工程,并发布了this问题,看看是否有人可以帮我理解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)

    }

}

我看到我有处理响应的代码(在didReceiveData中),但我不确定我需要实现什么才能进行监听;

  • 我是否需要“绑定”到侦听器端口(在本例中为61991)?
  • 我是否需要“加入多播组”?如果是这样,在什么地址?我尝试在“255.255.255.255”这样做,这在我构建时会产生setSocketOpt()错误。
  • 我知道我需要调用beginReceiving(),我可以在socket上完成所有这些操作,还是需要为侦听实例化一个单独的套接字?

修改:已解决

以下答案绝对帮助我解决了这个问题。似乎我没有得到回应,因为我还没有完全实现处理传入响应的方法。

根据下面答案中提供的代码,我添加了以下内容;

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

我还将此控制器设置为GCDAsyncSocketDelegate,这似乎可以解决问题。我能够在didReadData中阅读回复。

1 个答案:

答案 0 :(得分:3)

以下代码更改使我能够接收使用netcat从我的Mac发送的UDP数据包,但我的Harmony中心似乎没有发送任何内容,所以我不确定发送的数据是否正确。< / p>

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

}

从命令行,您可以使用命令

测试接收
echo -n "hello" | nc -4u -w1 x.x.x.x 61991