【问题标题】:Sockets with Swift带有 Swift 的套接字
【发布时间】:2015-04-12 13:13:19
【问题描述】:

我正在使用套接字创建我的 Swift 程序,我想知道是否有必要使用 GCDAsyncSocket 库?我正在尝试创建一个将字符串发送到我的 mac os x 应用程序的 iOS 应用程序。我以前用 Java 写过一个与此类似的套接字应用程序,所以我对套接字非常熟悉。我的服务器端(mac os)代码如下所示,我不确定如何处理客户端(iOS 端)

var bsocket: GCDAsyncSocket!

func applicationDidFinishLaunching(aNotification: NSNotification) {
    bsocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
    var port:UInt16 = 8090
    if (!bsocket.connectToHost("localhost", onPort: port, error: nil))
    {
        println("Error")
    }
    else
    {
        println("Connecting...")
    }
}

func socket(socket : GCDAsyncSocket, didReadData data:NSData, withTag tag:UInt16)
{
    var response = NSString(data: data, encoding: NSUTF8StringEncoding)
    println("Received Response")
}

func socket(socket : GCDAsyncSocket, didConnectToHost host:String, port p:UInt16)
{
    println("Connected to \(host) on port \(p).")

    var request:String = "Welcome to the server."
    var data:NSData = request.dataUsingEncoding(NSUTF8StringEncoding)!
    bsocket.writeData(data, withTimeout: -1.0, tag: 0)
    bsocket.readDataWithTimeout(-1.0, tag: 0)
}

【问题讨论】:

    标签: ios macos sockets swift


    【解决方案1】:

    来自 Ray Wenderlich.com http://www.raywenderlich.com/3932/networking-tutorial-for-ios-how-to-create-a-socket-based-iphone-app-and-server 的本教程很好地描述了连接到基本服务器套接字所需的客户端。它不做 websocket 协议中所需的任何握手、心跳和帧,因此它与 websockets 不兼容。您的代码没有显示 websocket 协议所需的任何握手,所以我认为这就是您想要的。如果您需要 websockets,请查看https://github.com/daltoniam/Starscream

    以下是我的 Swift 解释的基础知识。我最终得到了一个经理和一个连接:

    class Manager : NSObject {
        var conn = Connection()
    
        func connect() {
            let (host, port) = screen.getAddress()
            conn.connect(host, port: port)
        }
    
        func disconnect() {
            conn.disconnect()
        }
    
        func sendMessage(params:[String : AnyObject]) {
            let msg = "send_message:" + JSONStringify(params)
    
            let data : NSData = msg.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
            var buffer = [UInt8](count:data.length, repeatedValue:0)
            data.getBytes(&buffer)
    
            conn.outputStream.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length)
        }
    
        func JSONStringify(value: AnyObject) -> String {
            if NSJSONSerialization.isValidJSONObject(value) {
                if let data = NSJSONSerialization.dataWithJSONObject(value, options: nil, error: nil) {
                   if let string = NSString(data: data, encoding: NSUTF8StringEncoding) {
                       return string
                    }
                 }
             }
             return ""
         }
    }
    
    class Connection : NSObject, NSStreamDelegate {
    var serverAddress: CFString = "127.0.0.1"
    var serverPort: UInt32 = 8443
    
    private var inputStream: NSInputStream!
    private var outputStream: NSOutputStream!
    
    func connect(address: CFString, port:UInt32) {
        println("connecting...")
    
        var readStream:  Unmanaged<CFReadStream>?
        var writeStream: Unmanaged<CFWriteStream>?
    
        CFStreamCreatePairWithSocketToHost(nil, address, port, &readStream, &writeStream)
    
        // Documentation suggests readStream and writeStream can be assumed to
        // be non-nil. It might be wise to test if either is nil
        // and implement error-handling as needed.
    
        self.inputStream = readStream!.takeRetainedValue()
        self.outputStream = writeStream!.takeRetainedValue()
    
        self.inputStream.delegate = self
        self.outputStream.delegate = self
    
        self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
        self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
    
        self.inputStream.open()
        self.outputStream.open()
    }
    
    func disconnect() {
        self.inputStream.close()
        self.outputStream.close()
    }
    
    
    func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
        switch (eventCode){
            case NSStreamEvent.ErrorOccurred:
                NSLog("ErrorOccurred")
            case NSStreamEvent.EndEncountered:
                NSLog("EndEncountered")
            case NSStreamEvent.None:
                NSLog("None")
            case NSStreamEvent.HasBytesAvailable:
                NSLog("HasBytesAvaible")
                var buffer = [UInt8](count: 4096, repeatedValue: 0)
                while (inputStream.hasBytesAvailable){
                    var len = inputStream.read(&buffer, maxLength: buffer.count)
                    if(len > 0){
                        var output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding)
                        if (output != ""){
                            NSLog("server said: %@", output!)
                        }
                    } else {
                        println("empty string from stream")
                    }
                }
            case NSStreamEvent.allZeros:
                NSLog("allZeros")
            case NSStreamEvent.OpenCompleted:
                NSLog("OpenCompleted")
            case NSStreamEvent.HasSpaceAvailable:
                NSLog("HasSpaceAvailable")
            default: println("default reached. unknown stream event")
            }
        }
    }
    

    您可能还会发现这些链接对 Swift 中的消息传递很有用:

    我不确定此代码中的 JSON 转换是否正常工作。我发现我需要 websockets,所以不再使用它。

    【讨论】:

      【解决方案2】:

      如果 iOS 设备只是客户端而不是服务器,您可以使用 NSStream。

      【讨论】:

      • iOS 将只是一个客户端,我只需要它向服务器发送一个“字符串”,然后发回它收到它的确认。这适用于 NSStream 吗?我马上去谷歌上搜索一下。
      【解决方案3】:

      假设当您说“socket”时,您的意思是“web socket”,我会考虑使用 Square 的 Socket Rocket。它确实做得很好,并且抽象了使用 Web 套接字的困难部分。

      https://github.com/square/SocketRocket

      【讨论】:

      • 我为什么要使用网络套接字?我不是从浏览器运行的。
      猜你喜欢
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-16
      • 2012-05-23
      • 1970-01-01
      相关资源
      最近更新 更多