2016-02-13 109 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