首页 文章

Swift:使用GCDAsyncUdpSocket接收UDP

提问于
浏览
17

背景:

我希望能够在我的iOS应用程序和服务器之间发送和接收UDP数据包 . 服务器将每个传入的消息回送给应用程序的客户端 . The server is tested and confirmed working . 我有一个StartViewController,启动两个实现GCDAsyncUdpSocketDelegate的类,一个用于发送,一个用于接收 . "sending socket"正在运行,服务器接收消息 .

问题:

应用程序在发送后永远不会收到回传消息 . 听取套接字设置的东西可能是错误的,因为didReceiveData永远不会被调用 .

我完全错了吗?

开始:

class StartViewController: UIViewController {

   var inSocket : InSocket!
   var outSocket : OutSocket!

   override func viewDidLoad() {
       super.viewDidLoad()
       inSocket = InSocket()
       outSocket = OutSocket()
   }

   @IBAction func goButton(sender: UIButton) {
       outSocket.send("This is a message!")
   }
}

接收:

class InSocket: NSObject, GCDAsyncUdpSocketDelegate {

   let IP = "255.255.255.255"
   let PORT:UInt16 = 5556
   var socket:GCDAsyncUdpSocket!

   override init(){
       super.init()
       setupConnection()
   }

   func setupConnection(){
       var error : NSError?
       socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
       socket.bindToPort(PORT, error: &error)
       socket.enableBroadcast(true, error: &error)
       socket.joinMulticastGroup(IP, error: &error)
       socket.beginReceiving(&error)
   }

   func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!,      withFilterContext filterContext: AnyObject!) {
       println("incoming message: \(data)");
   }
}

发送:

class OutSocket: NSObject, GCDAsyncUdpSocketDelegate {

   let IP = "90.112.76.180"
   let PORT:UInt16 = 5556
   var socket:GCDAsyncUdpSocket!

   override init(){
       super.init()
       setupConnection()
   }

   func setupConnection(){
       var error : NSError?
       socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
       socket.connectToHost(IP, onPort: PORT, error: &error)
   }

   func send(message:String){
       let data = message.dataUsingEncoding(NSUTF8StringEncoding)
       socket.sendData(data, withTimeout: 2, tag: 0)
   }

   func udpSocket(sock: GCDAsyncUdpSocket!, didConnectToAddress address: NSData!) {
       println("didConnectToAddress");
   }

   func udpSocket(sock: GCDAsyncUdpSocket!, didNotConnect error: NSError!) {
       println("didNotConnect \(error)")
   }

   func udpSocket(sock: GCDAsyncUdpSocket!, didSendDataWithTag tag: Int) {
       println("didSendDataWithTag")
   } 

   func udpSocket(sock: GCDAsyncUdpSocket!, didNotSendDataWithTag tag: Int, dueToError error: NSError!) {
        println("didNotSendDataWithTag")
   }
}

Edit: 添加了遗忘的代码行 .

2 回答

  • 12

    我终于让它使用这个套接字设置:

    func setupConnection(){
        var error : NSError?
        socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
        socket.bindToPort(PORT, error: &error)
        socket.connectToHost(SERVER_IP, onPort: PORT, error: &error)
        socket.beginReceiving(&error)
        send("ping")
    }
    
    func send(message:String){
       let data = message.dataUsingEncoding(NSUTF8StringEncoding)
       socket.sendData(data, withTimeout: 2, tag: 0)
    }
    
  • 1

    Apple Swift version 4.2.1 Well Tested UDP Example:-

    第1步: - pod 'CocoaAsyncSocket'

    第2步: - UIViewController 中的 import CocoaAsyncSocket .

    第3步: - UIViewController

    import UIKit
    import CocoaAsyncSocket
    
    class ViewController: UIViewController {
        @IBOutlet weak var btnOnOff: LightButton!
        @IBOutlet weak var lblStatus: UILabel!
        var inSocket : InSocket!
        var outSocket : OutSocket!
        override func viewDidLoad() {
            super.viewDidLoad()
            lblStatus.isHidden = true
            inSocket = InSocket()
            outSocket = OutSocket()
            outSocket.setupConnection {
                self.lblStatus.isHidden = false
            }
        }
        @IBAction func btnLight(_ sender: Any) {
            let signal:Signal = Signal()
            self.outSocket.send(signal: signal)
        }
    }
    

    第4步: - Reciving Socket

    //Reciving End...
    class InSocket: NSObject, GCDAsyncUdpSocketDelegate {
       //let IP = "10.123.45.2"
        let IP = "127.0.0.1"
        let PORT:UInt16 = 5001
        var socket:GCDAsyncUdpSocket!
        override init(){
            super.init()
            setupConnection()
        }
        func setupConnection(){
            socket = GCDAsyncUdpSocket(delegate: self, delegateQueue:DispatchQueue.main)
            do { try socket.bind(toPort: PORT)} catch { print("")}
            do { try socket.enableBroadcast(true)} catch { print("not able to brad cast")}
            do { try socket.joinMulticastGroup(IP)} catch { print("joinMulticastGroup not procceed")}
            do { try socket.beginReceiving()} catch { print("beginReceiving not procceed")}
        }
        //MARK:-GCDAsyncUdpSocketDelegate
        func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
              print("incoming message: \(data)");
              let signal:Signal = Signal.unarchive(d: data)
              print("signal information : \n first \(signal.firstSignal) , second \(signal.secondSignal) \n third \(signal.thirdSignal) , fourth \(signal.fourthSignal)")
    
        }
        func udpSocket(_ sock: GCDAsyncUdpSocket, didNotConnect error: Error?) {
        }
    
        func udpSocketDidClose(_ sock: GCDAsyncUdpSocket, withError error: Error?) {
        }
    }
    

    第5步: - Sending Socket..

    //Sending End...
    class OutSocket: NSObject, GCDAsyncUdpSocketDelegate {
        // let IP = "10.123.45.1"
        let IP = "127.0.0.1"
        let PORT:UInt16 = 5001
        var socket:GCDAsyncUdpSocket!
        override init(){
            super.init()
    
        }
        func setupConnection(success:(()->())){
            socket = GCDAsyncUdpSocket(delegate: self, delegateQueue:DispatchQueue.main)
              do { try socket.bind(toPort: PORT)} catch { print("")}
              do { try socket.connect(toHost:IP, onPort: PORT)} catch { print("joinMulticastGroup not procceed")}
              do { try socket.beginReceiving()} catch { print("beginReceiving not procceed")}
            success()
        }
        func send(signal:Signal){
            let signalData = Signal.archive(w: signal)
            socket.send(signalData, withTimeout: 2, tag: 0)
        }
        //MARK:- GCDAsyncUdpSocketDelegate
        func udpSocket(_ sock: GCDAsyncUdpSocket, didConnectToAddress address: Data) {
            print("didConnectToAddress");
        }
        func udpSocket(_ sock: GCDAsyncUdpSocket, didNotConnect error: Error?) {
            if let _error = error {
                print("didNotConnect \(_error )")
            }
        }
        func udpSocket(_ sock: GCDAsyncUdpSocket, didNotSendDataWithTag tag: Int, dueToError error: Error?) {
              print("didNotSendDataWithTag")
        }
        func udpSocket(_ sock: GCDAsyncUdpSocket, didSendDataWithTag tag: Int) {
            print("didSendDataWithTag")
        }
    }
    

    第6步: - 你的 Signal 数据你将 Send/Recieve

    import Foundation
    struct Signal {
        var firstSignal:UInt16 = 20
        var secondSignal:UInt16 = 30
        var thirdSignal: UInt16  = 40
        var fourthSignal: UInt16 = 50
        static func archive(w:Signal) -> Data {
            var fw = w
            return Data(bytes: &fw, count: MemoryLayout<Signal>.stride)
        }
        static func unarchive(d:Data) -> Signal {
            guard d.count == MemoryLayout<Signal>.stride else {
                fatalError("BOOM!")
            }
            var s:Signal?
            d.withUnsafeBytes({(bytes: UnsafePointer<Signal>)->Void in
                s = UnsafePointer<Signal>(bytes).pointee
            })
            return s!
        }
    }
    

相关问题