【问题标题】:Receiving Data from NSInputStream in Swift在 Swift 中从 NSInputStream 接收数据
【发布时间】:2014-12-09 06:08:34
【问题描述】:

我尝试在 Swift 中使用 NSOutputStream 和 NSInputStream 发送和接收数据。数据发送正常,但我对接收有一些疑问。

我找到了处理 NSStreamEvent 的解决方案,我已经尝试过了。

首先是我初始化连接的函数:

func initNetworkCommunication(){  
    var host : CFString = "127.0.0.1"
    var port : UInt32 = 7001
    var readstream : Unmanaged<CFReadStream>?
    var writestream : Unmanaged<CFWriteStream>?
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, &readstream, &writestream)

    inputstream = readstream!.takeRetainedValue()
    outputstream = writestream!.takeRetainedValue()

    inputstream.delegate = self
    outputstream.delegate = self


    inputstream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
    outputstream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)

    inputstream.open()
    outputstream.open()   
}

这部分工作正常。我已将代表设置为 self,因此我应该能够处理此类中的 NSStreamEvents。

func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
    switch (eventCode){
    case NSStreamEvent.OpenCompleted:
        NSLog("Stream opened")
        break
    case NSStreamEvent.HasBytesAvailable:
        NSLog("HasBytesAvailable")
        break
    case NSStreamEvent.ErrorOccurred:
         NSLog("ErrorOccurred")
        break
    case NSStreamEvent.EndEncountered:
        NSLog("EndEncountered")
        break
    default:
        NSLog("unknown.")
    }
}

据我了解,每次有数据到达时,它应该打印“HasBytesAvaible”,但它打印“未知”。每次。所以我玩了一点,它适用于这个:

func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {

    var buffer = [UInt8](count: 4096, repeatedValue: 0)
    while (inputstream.hasBytesAvailable){
        let result: Int = inputstream.read(&buffer, maxLength: buffer.count)
    }

    switch (eventCode){
    case NSStreamEvent.OpenCompleted:
        NSLog("Stream opened")
        break
    case NSStreamEvent.HasBytesAvailable:
        NSLog("HasBytesAvailable")
        var output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding)
        NSLog("output: %@", output)
        receiveMessage(output) //only adds the message to an array
        break
    case NSStreamEvent.ErrorOccurred:
        NSLog("ErrorOccurred")
        break
    case NSStreamEvent.EndEncountered:
          NSLog("EndEncountered")
        break
    default:
        NSLog("unknown.")
    }
}

它是这样工作的,但我想问你这是否是正确的方法?此时的最佳做法是什么?

更新 几周前我再次研究它并找出了我的错误。所以这是工作代码。

func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
        switch (eventCode){
    case NSStreamEvent.ErrorOccurred:
        NSLog("ErrorOccurred")
        break
    case NSStreamEvent.EndEncountered:
        NSLog("EndEncountered")
        break
    case NSStreamEvent.None:
        NSLog("None")
        break
    case NSStreamEvent.HasBytesAvailable:
        NSLog("HasBytesAvaible")
        var buffer = [UInt8](count: 4096, repeatedValue: 0)
        if ( aStream == inputstream){

            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!)
                    }
                }
            } 
        }
        break
    case NSStreamEvent.allZeros:
        NSLog("allZeros")
        break
    case NSStreamEvent.OpenCompleted:
        NSLog("OpenCompleted")
        break
    case NSStreamEvent.HasSpaceAvailable:
        NSLog("HasSpaceAvailable")
        break
  }

【问题讨论】:

  • 您好,此解决方案一次可用于多个响应?
  • 上面的代码是用来接收消息的,不是用来响应的。有使用套接字发送和响应的框架,也许看看 socket.io socket.io/blog/socket-io-on-ios
  • 是的,它用于接收消息,但我想问你,如果我同时收到来自服务器的多个响应,它会处理吗?

标签: swift inputstream nsstream


【解决方案1】:

您错过了事件hasSpaceAvailable,我预计它会在显示“未知”时发生。它告诉您它已准备好接收更多数据。

一般来说,我避免在枚举的 switch 语句中使用default,因为编译器会告诉你什么时候错过了。

【讨论】:

  • 几周前我就知道了。我会在这里接受你的回答,因为你是对的。这是我的错误。
  • 很高兴您对它进行了排序 - 我在回答后才知道您的问题的日期!
  • @Alexander 这个解决方案一次可以用于多个响应吗?在(更新)
  • @K.Shrikant 我认为如果你创建一个新问题会得到更好的答案
【解决方案2】:

我正在使用hoedding编写的代码,并注意到一个错误。行:

var output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding)

应替换为:

var output = NSString(bytes: &buffer, length: len, encoding: NSUTF8StringEncoding)

您必须在output var 中仅获取服务器返回的字符数,而不是缓冲区的完整长度,否则您将从之前的请求中得到垃圾。

【讨论】:

    猜你喜欢
    • 2015-07-13
    • 2021-05-06
    • 1970-01-01
    • 2016-02-13
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    相关资源
    最近更新 更多