这是我在Swift中的第一个程序。我正在使用Xcode在swift中编写基本命令行(UDP)服务器/监听器。我能够发送数据,即带有字符的字符串'测试'通过" sendData"电话(通过wireshark验证)。但是,我似乎无法调用任何委托回调。对于" sendData",我已经检查了#GCDAsyncUdpSocket主文件中的实现,我看到没有调用任何代理,除非发送我们看到一个特定的错误(解决错误),其中" didNOTSendDataWithTag"叫做。
但是如果" beginReceiving"被调用,它不会调用" didReceiveData"打回来。我似乎无法弄清楚原因。另外" beginReceiving根据其实现假设是递归的(我自己永远调用)。但是我的程序很快就会退出而没有任何错误。任何帮助将非常感激。
import Cocoa
import CocoaAsyncSocket
class udpListener : GCDAsyncUdpSocketDelegate {
var udpSock : GCDAsyncUdpSocket?
let listenPort : UInt16 = 14000
let data = "testing".dataUsingEncoding(NSUTF8StringEncoding)
let toAddress = "127.0.0.1"
let connectPort : UInt16 = 14001
init () {
udpSock = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
do {
try udpSock!.bindToPort(listenPort, interface: "lo0") // Swift automatically translates Objective-C methods that produce
// errors into methods that throw an error according to Swift’s native error handling functionality.
}
catch _ as NSError {
print("Issue with binding to Port")
return }
do {
try udpSock!.beginReceiving()
}
catch _ as NSError {
print("Issue with receciving data")
return }
}
func sendData() {
udpSock!.sendData(data, toHost: toAddress, port: connectPort, withTimeout: -1, tag: 0)
}
}
// Delegate CallBacks
@objc func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) {
let str = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(str)
}
@objc func udpSocket(sock: GCDAsyncUdpSocket!, didSendDataWithTag tag: Int) {
print("didSendDataWithTag")
}
@objc func udpSocket(sock: GCDAsyncUdpSocket!, didNotSendDataWithTag tag: Int, dueToError error: NSError!) {
print("didNOTSendDataWithTag")
}
}
我从主swift文件中实例化该类的实例,并按此顺序调用其方法。这是正确的还是我在这里遗漏了什么
import Foundation
var dnsListener = udpListener()
dnsListener.sendData()
这里是wireshark结果的屏幕截图
答案 0 :(得分:0)
主线程没有任何循环来阻止它退出,因此在发送消息之前执行完毕。如果向main()添加循环或延迟,则将发送消息。 此代码的另一个问题是委托被设置为在主队列上运行。主队列忙于运行循环或延迟,并且无法执行委托代码。通过创建新的委托队列,委托函数中的代码将运行。
以下代码适用于Swift 3。
主要代码:
import Foundation
var dnsListener = UdpListener()
for i in 1...3 {
print("Sending data \(i)")
dnsListener.sendData()
sleep(3)
}
print("Execution finished")
UdpListener代码:
import Foundation
import CocoaAsyncSocket
class UdpListener : NSObject, GCDAsyncUdpSocketDelegate {
var udpSock: GCDAsyncUdpSocket?
let listenPort: UInt16 = 14000
let data = "testing".data(using: String.Encoding.utf8)
let toAddress = "127.0.0.1"
let connectPort: UInt16 = 14001
override init() {
super.init()
let utilityQueue = DispatchQueue(label: "com.stackoverflow.UdpListener.utilityQueue", qos: .utility)
udpSock = GCDAsyncUdpSocket(delegate: self, delegateQueue: utilityQueue)
do {
try udpSock!.bind(toPort: listenPort, interface: "lo0")
} catch {
print("Issue with binding to Port")
return
}
do {
try udpSock!.beginReceiving()
} catch {
print("Issue with receciving data")
return
}
}
func sendData() {
udpSock!.send(data!, toHost: toAddress, port: connectPort, withTimeout: -1, tag: 0)
}
// Delegate CallBacks
func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
let str = String(data: data, encoding: String.Encoding.utf8)
if let str = str {
print(str)
} else {
print("Could not decode received data")
}
}
func udpSocket(_ sock: GCDAsyncUdpSocket, didSendDataWithTag tag: Int) {
print("didSendDataWithTag")
}
func udpSocket(_ sock: GCDAsyncUdpSocket, didNotSendDataWithTag tag: Int, dueToError error: Error?) {
print("didNOTSendDataWithTag")
}
}