我正在使用Xcode在swift中编写基本命令行(UDP)服务器/监听器。 #GCDAsyncUdpSocket不会调用我的任何代理人

时间:2016-06-28 16:03:16

标签: xcode swift sockets udp

这是我在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结果的屏幕截图

1 个答案:

答案 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")
    }
}