在 Swift 中实现 UDP "Listener"?
Implementing A UDP "Listener" In Swift?
我一直在尝试对一个项目进行某种逆向工程以发现我网络上的罗技 Harmony Hub 设备,并发布了 问题以查看是否有人可以帮助我理解 UDP 广播。答案解释说我已经实现了 UDP 广播的 send 部分,但是我还没有实现 "listen" 的任何响应。这就是我挣扎的地方。这是我的发送代码;
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
中),但我不确定我需要实施什么才能开始收听;
- 我需要 "bind" 到侦听器端口(在本例中为 61991)吗?
- 我需要"join the multicast group"吗?如果是这样,在什么地址?我尝试在“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
.
中的回复
以下代码更改使我能够接收使用 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
我一直在尝试对一个项目进行某种逆向工程以发现我网络上的罗技 Harmony Hub 设备,并发布了
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
中),但我不确定我需要实施什么才能开始收听;
- 我需要 "bind" 到侦听器端口(在本例中为 61991)吗?
- 我需要"join the multicast group"吗?如果是这样,在什么地址?我尝试在“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
.
以下代码更改使我能够接收使用 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