2016-02-13 85 views
2

我一直在尝试对项目进行一定程度的逆向工程,以发现我的网络上的Logitech Harmony Hub设备,并发布this问题,以查看是否有人可以帮助我理解UDP广播。答案解释说我已经实现了发送部分的UDP广播,但是我没有实现任何东西来“听”回应。这就是我挣扎的地方。这里是我的发送的代码;在Swift中实现一个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中的回复。

回答

2

以下代码更改使我可以接收使用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) 
    } 

} 

在命令行中,你可以测试使用命令

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

嗨@ Paulw11接受 - 谢谢你澄清这一点。使用您的代码,我也能够接收通过终端发送的消息,并在我的应用程序的特定端口上接收它们。我和Harmony Hub有着相同的经历。作为测试,我在我的应用程序中尝试了'self.socket.bindToPort(5224)',并使用我的iPhone /同一个WiFi网络上的Harmony应用程序假装找到一个新的集线器。它确实以'_logitech-reverse-bonjour._tcp.local。\ nXXXXX'的形式发送了一条消息,不过每次都有不同的端口变为XXXXX。 – ZbadhabitZ

+0

此外,@ Paulw11 - 我实际上发现,我试图将该项目基于的NODE.JS项目现在无法找到我已建立的Harmony Hub(它能够在上周进行)。我不确定确切的步骤,但它几乎就像运行NODE.JS项目让它一次找到集线器,然后集线器不再响应UDP广播直到它被重置(拔掉并插回)。我仍然试图弄清楚。 – ZbadhabitZ

+0

接下来,我现在意识到iOS应用程序没有收到来自Harmony Hub的响应。作为一个测试,我试图启动node.js脚本以发现另一台计算机上的Harmony Hubs,并且我可以确认发送的消息是此代码中正在使用的内容。但是,它看起来像node.js项目实际上是实例化它自己的服务器(在responseCollector.js服务器),它从Harmony接收响应;如果可能的话,它不仅仅是在收听61991港口。 – ZbadhabitZ