简体   繁体   English

Swift:使用 GCDAsyncUdpSocket 接收 UDP

[英]Swift: Receive UDP with GCDAsyncUdpSocket

BACKGROUND:背景:

I want to be able to send and receive UDP packets between my iOS app and a server.我希望能够在我的 iOS 应用程序和服务器之间发送和接收 UDP 数据包。 The server echoes back every incoming message to the client the app.服务器将每条传入消息回显给客户端应用程序。 The server is tested and confirmed working .服务器经过测试并确认正常工作 I have a StartViewController which starting up two classes that implements GCDAsyncUdpSocketDelegate, one for sending and one for receiving.我有一个 StartViewController,它启动了两个实现 GCDAsyncUdpSocketDelegate 的类,一个用于发送,一个用于接收。 The "sending socket" is working, the server receives the messages. “发送套接字”正在工作,服务器接收消息。

PROBLEM:问题:

The app never get the incoming message back after it been sent.应用程序永远不会在发送后取回传入的消息。 Something with the listening socket setup is probably wrong since didReceiveData never get called.监听套接字设置可能有问题,因为 didReceiveData 永远不会被调用。

Have I done this completely wrong?我这样做是完全错误的吗?

Start:开始:

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

Receive:收到:

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

Send:发送:

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: Added forgotten code line.编辑:添加了忘记的代码行。

I finally got it to work with this socket setup:我终于让它与这个套接字设置一起工作:

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 version 4.2.1 Well Tested UDP Example:- Apple Swift 4.2.1 版经过良好测试的 UDP 示例:-

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

STEP 2 :- import CocoaAsyncSocket in your UIViewController .第 2 import CocoaAsyncSocket :- 在UIViewController import CocoaAsyncSocket

STEP 3 :- UIViewController第 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)
    }
}

STEP 4 :- Reciving Socket第 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?) {
    }
}

STEP 5 :- Sending Socket..第 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")
    }
}

STEP 6 :- Your Signal Data which you will Send/Recieve第 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