Swift套接字 [英] Sockets with Swift

查看:69
本文介绍了Swift套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  var bsocket:GCDAsyncSocket!func applicationDidFinishLaunching(aNotification:NSNotification){bsocket = GCDAsyncSocket(代理:自我,委托队列:dispatch_get_main_queue())var端口:UInt16 = 8090如果(!bsocket.connectToHost("localhost",onPort:端口,错误:无)){println(错误")}别的{println(正在连接...")}}func socket(socket:GCDAsyncSocket,didReadData data:NSData,withTag标签:UInt16){var response = NSString(data: data, encoding: NSUTF8StringEncoding)println(收到的响应")}func套接字(套接字:GCDAsyncSocket,didConnectToHost主机:字符串,端口p:UInt16){println(已连接到端口\(p)上的\(主机).")var request:String =欢迎使用服务器."var data:NSData = request.dataUsingEncoding(NSUTF8StringEncoding)!bsocket.writeData(数据,withTimeout:-1.0,标签:0)bsocket.readDataWithTimeout(-1.0, 标签: 0)} 

解决方案

Ray Wenderlich.com的本教程 https://github.com/daltoniam/Starscream

以下是我的Swift解释的基础.我最终得到一个Manager和一个Connection:

  class Manager:NSObject {var conn = Connection()func connect(){let(主机,端口)= screen.getAddress()conn.connect(主机,端口:端口)}func connect(){conn.disconnect()}func sendMessage(params:[String:AnyObject]){让msg ="send_message:" + JSONStringify(params)let data:NSData = msg.dataUsingEncoding(NSUTF8StringEncoding,allowLossyConversion:false)!var缓冲区= [UInt8](count:data.length,repeatedValue:0)data.getBytes(& buffer)conn.outputStream.write(UnsafePointer< UInt8>(data.bytes),maxLength:data.length)}func JSONStringify(value:AnyObject)->细绳 {如果NSJSONSerialization.isValidJSONObject(value){如果让数据= NSJSONSerialization.dataWithJSONObject(值,选项:无,错误:无){如果让string = NSString(数据:数据,编码:NSUTF8StringEncoding){返回字符串}}}返回 ""}}类连接:NSObject,NSStreamDelegate {var serverAddress:CFString ="127.0.0.1"var serverPort:UInt32 = 8443私人var inputStream:NSInputStream!私有var outputStream:NSOutputStream!func connect(地址:CFString,端口:UInt32){println(正在连接...")var readStream:非托管?var writeStream:不受管理的< CFWriteStream> ;?CFStreamCreatePairWithSocketToHost(nil,地址,端口,& readStream和& writeStream)//文档建议将readStream和writeStream假定为//不为nil.测试是否为零可能是明智的//并根据需要实施错误处理.self.inputStream = readStream!.takeRetainedValue()self.outputStream = writeStream!.takeRetainedValue()self.inputStream.delegate =自我self.outputStream.delegate =自我self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(),forMode:NSDefaultRunLoopMode)self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(),forMode:NSDefaultRunLoopMode)self.inputStream.open()self.outputStream.open()}func connect(){self.inputStream.close()self.outputStream.close()}func stream(aStream:NSStream,handleEvent eventCode:NSStreamEvent){开关(事件代码){发生NSStreamEvent.ErrorOccurred的情况:NSLog("ErrorOccurred")案例NSStreamEvent.EndEncountered:NSLog("EndEncountered")案例NSStreamEvent.None:NSLog(无")情况NSStreamEvent.HasBytesAvailable:NSLog("HasBytesAvaible")var缓冲区= [UInt8](计数:4096,重复值:0)而(inputStream.hasBytesAvailable){var len = inputStream.read(& buffer,maxLength:buffer.count)如果(len> 0){var输出= NSString(字节:& buffer,长度:buffer.count,编码:NSUTF8StringEncoding)如果(输出!="){NSLog(服务器说:%@",输出!)}} 别的 {println(流中的空字符串")}}案例NSStreamEvent.allZeros:NSLog("allZeros")案例NSStreamEvent.OpenCompleted:NSLog("OpenCompleted")案例NSStreamEvent.HasSpaceAvailable:NSLog("HasSpaceAvailable")默认值:println(达到默认值.未知流事件")}}} 

您可能还会发现这些链接对于在Swift中进行消息传递非常有用:

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

I'm creating my Swift program with sockets and I was wondering if it's neccessary to use the GCDAsyncSocket library? I'm trying to create an iOS app that sends strings to my mac os x app. I've written a socket application similar to this before in Java so I'm pretty familiar with sockets. My server side (mac os) code looks like this, I am unsure how to approach the client side (iOS side)

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

解决方案

This tutorial from Ray Wenderlich.com http://www.raywenderlich.com/3932/networking-tutorial-for-ios-how-to-create-a-socket-based-iphone-app-and-server has a good description of the client side needed to connect to a basic server socket. It does not do any of the handshaking, heartbeat and framing required in the websocket protocol, so it is not compatible with websockets. Your code doesn't show any of the handshaking required by the websocket protocol, so I assume that's what you want. If you need websockets, take a look at https://github.com/daltoniam/Starscream

Here are the basics of my Swift interpretation. I ended up with a Manager and a Connection:

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

You might also find these links useful for messaging in Swift:

I'm not sure the JSON conversion in this code is working correctly. I discovered that I needed websockets, so this is no longer used.

这篇关于Swift套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆