Swift:NSStreamDelegate在发送后没有收到NSStreamEvent.HasBytesAvailable

时间:2015-02-01 06:50:29

标签: ios sockets swift

我正试图在swift中打开一个与imap服务器对话的套接字。通过套接字发送命令后,我没有在inputStream上看到NSStreamEvent.HasBytesAvailable事件。

以下是我的代码的日志输出:

# connecting to imap.gmail.com:993
NSStreamEvent.OpenCompleted <__NSCFInputStream: 0x7fdf80543590>
NSStreamEvent.OpenCompleted <__NSCFOutputStream: 0x7fdf80540e30>
NSStreamEvent.HasBytesAvailable <__NSCFInputStream: 0x7fdf80543590>
NSStreamEvent.HasSpaceAvailable <__NSCFOutputStream: 0x7fdf80540e30>
< * OK Gimap ready for requests from 50.156.116.68 ra6mb82064609pab

> ABC1 CAPABILITY
NSStreamEvent.HasSpaceAvailable <__NSCFOutputStream: 0x7fdf80540e30>

我的代码

我有一个带连接,阅读和发送按钮的简单故事板

ViewController.swift

import UIKit

class ViewController: UIViewController {

  var socketConnection :SocketConnection!

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }

  @IBAction func connect() {
    socketConnection = SocketConnection(host: "imap.gmail.com", port: 993, useSSL: true)
    socketConnection.connect()
  }

  @IBAction func read() {
    socketConnection.read()
  }

  @IBAction func send() {
    socketConnection.send("ABC1 CAPABILITY\n")
  }
}

Socketconnection.swift

import Foundation

class SocketConnection: NSObject, NSStreamDelegate {

  let host :String
  let port :UInt32
  let useSSL :Bool

  let bufferSize = 4096
  let encoding : UInt = NSUTF8StringEncoding

  var inputStream : NSInputStream?
  var outputStream : NSOutputStream?

  init(host: String, port:UInt32, useSSL:Bool){
    self.host = host
    self.port = port
    self.useSSL = useSSL
    super.init()
  }

  func stream(aStream: NSStream, handleEvent aStreamEvent: NSStreamEvent) {
    switch aStreamEvent {
    case NSStreamEvent.OpenCompleted:
      println("NSStreamEvent.OpenCompleted \(aStream.description)")
    case NSStreamEvent.HasBytesAvailable:
      println("NSStreamEvent.HasBytesAvailable \(aStream.description)")
    case NSStreamEvent.HasSpaceAvailable:
      println("NSStreamEvent.HasSpaceAvailable \(aStream.description)")
    case NSStreamEvent.EndEncountered:
      println("NSStreamEvent.EndEncountered \(aStream.description)")
    case NSStreamEvent.None:
      println("NSStreamEvent.None \(aStream.description)")
    case NSStreamEvent.ErrorOccurred:
      println("NSStreamEvent.ErrorOccurred \(aStream.description)")
    default:
      println("# something weird happend")
    }
  }

  func connect() {
    println("# connecting to \(host):\(port)")
    var cfReadStream : Unmanaged<CFReadStream>?
    var cfWriteStream : Unmanaged<CFWriteStream>?

    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, &cfReadStream, &cfWriteStream)
    inputStream = cfReadStream!.takeUnretainedValue()
    outputStream = cfWriteStream!.takeUnretainedValue()

    if self.useSSL {
      inputStream!.setProperty(kCFStreamSocketSecurityLevelNegotiatedSSL, forKey: kCFStreamPropertySocketSecurityLevel)
      outputStream!.setProperty(kCFStreamSocketSecurityLevelNegotiatedSSL, forKey: kCFStreamPropertySocketSecurityLevel)
    }

    inputStream!.delegate = self
    outputStream!.delegate = self

    inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
    outputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)

    inputStream!.open()
    outputStream!.open()
  }

  func read(){
    var buffer = [UInt8](count: bufferSize, repeatedValue: 0)
    var output: String = ""
    while (self.inputStream!.hasBytesAvailable){
      var bytesRead: Int = inputStream!.read(&buffer, maxLength: buffer.count)
      if bytesRead >= 0 {
        output += NSString(bytes: UnsafePointer(buffer), length: bytesRead, encoding: encoding)!
      } else {
        println("# error")
      }
      println("< \(output)")
    }
  }

  func send(message:String){
    if (self.outputStream!.hasSpaceAvailable){
      let data:NSData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
      let bytesWritten = self.outputStream!.write(UnsafePointer(data.bytes), maxLength: data.length)
      println("> \(message)")
    } else {
      println("# steam busy")
    }
  }

}

使用openssl s_client

可以使用相同的命令
openssl s_client -connect imap.gmail.com:993 -crlf
... SSL HANDSHAKE ...
---
* OK Gimap ready for requests from 50.156.116.68 st4mb69201226pbc
ABC1 CAPABILITY
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN
ABC1 OK Thats all she wrote! st4mb69201226pbc

0 个答案:

没有答案