我正试图在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