簡體   English   中英

Swift:使用 GCDAsyncUdpSocket 接收 UDP

[英]Swift: Receive UDP with GCDAsyncUdpSocket

背景:

我希望能夠在我的 iOS 應用程序和服務器之間發送和接收 UDP 數據包。 服務器將每條傳入消息回顯給客戶端應用程序。 服務器經過測試並確認正常工作 我有一個 StartViewController,它啟動了兩個實現 GCDAsyncUdpSocketDelegate 的類,一個用於發送,一個用於接收。 “發送套接字”正在工作,服務器接收消息。

問題:

應用程序永遠不會在發送后取回傳入的消息。 監聽套接字設置可能有問題,因為 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")
   }
}

編輯:添加了忘記的代碼行。

我終於讓它與這個套接字設置一起工作:

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)
}

Apple Swift 4.2.1 版經過良好測試的 UDP 示例:-

第 1 pod 'CocoaAsyncSocket' :- pod 'CocoaAsyncSocket'

第 2 import CocoaAsyncSocket :- 在UIViewController import CocoaAsyncSocket

第 3 UIViewController :- 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 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 proceed")}
        do { try socket.beginReceiving()} catch { print("beginReceiving not proceed")}
    }
    //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 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 proceed")}
          do { try socket.beginReceiving()} catch { print("beginReceiving not proceed")}
        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:- 您將發送/接收的信號數據

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!
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM