2016-06-09 78 views
0

我正在嘗試使用NSOutputstream和NSInputstream來編寫和讀取每個區間,比如說5秒。這是以P2P方式與Windows上的C#程序進行通信。使用NSOutputstream和NSInputstream來寫入和讀取每個區間

我想使用NSOutputstream每5秒向C#程序發送一個請求,然後NSInputstream將讀取C#程序的響應。

目前我有:

class Connection : NSObject, NSStreamDelegate { 
var serverAddress: CFString 
let serverPort: UInt32 = 11000 

private var inputStream: NSInputStream! 
private var outputStream: NSOutputStream! 

init(serverAddress: CFString) { 
    self.serverAddress = serverAddress 
} 

func connect() { 
    print("connecting...") 

    var readStream: Unmanaged<CFReadStream>? 
    var writeStream: Unmanaged<CFWriteStream>? 

    CFStreamCreatePairWithSocketToHost(nil, self.serverAddress, self.serverPort, &readStream, &writeStream) 

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

    print("connected...") 
} 

func disconnect() { 
    self.inputStream.close() 
    self.outputStream.close() 
} 

func receive() -> String { 
    let data: NSData = "GiveMeCurrentTime".dataUsingEncoding(NSUTF8StringEncoding)! 

    let bytesWritten = outputStream.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length) 

    print("wrote \(bytesWritten) bytes") 

    var buffer = [UInt8](count: 100, repeatedValue: 0) 
    inputStream.read(&buffer,maxLength: buffer.count) 

    let currentTime = String.fromCString(UnsafePointer(buffer)) 
    print("Data received is \(currentTime)") 


    return currentTime 
} 

func stream(stream: NSStream, handleEvent eventCode: NSStreamEvent) { 
    //print("stream event") 

    if stream === inputStream { 
     switch eventCode { 
     case NSStreamEvent.ErrorOccurred: 
      print("input: ErrorOccurred: \(stream.streamError?.description)") 
     case NSStreamEvent.OpenCompleted: 
      print("input: OpenCompleted") 
     case NSStreamEvent.HasBytesAvailable: 
      print("input: HasBytesAvailable") 
      break; 
     case NSStreamEvent.HasSpaceAvailable: 
      break; 
     default: 
      print("\(eventCode)") 
      break 
     } 
    } 
    else if stream === outputStream { 
     switch eventCode { 
     case NSStreamEvent.ErrorOccurred: 
      print("output: ErrorOccurred: \(stream.streamError?.description)") 
     case NSStreamEvent.OpenCompleted: 
      print("output: OpenCompleted") 
     case NSStreamEvent.HasSpaceAvailable: 
      print("output: HasSpaceAvailable") 
      // Here you can write() to `outputStream` 
      break; 
     default: 
      print("\(eventCode)") 
      break 
     } 
    } 
} 

連接類將被用作下面的NSTimer和NSRunLoop:

func start(ipAddress ipAddress: String) { 
     self.conn = Connection(serverAddress: ipAddress) 
     self.conn!.connect() 
     self.sendTimer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "getTimeAndUpdateUI", userInfo: nil, repeats: true) 
     NSRunLoop.currentRunLoop().addTimer(self.sendTimer!, forMode: NSDefaultRunLoopMode) 
    } 
} 

func getTimeAndUpdateUI() { 
    let time = self.conn!.receive() 
    self.timeLabel.text = "Current time is \(time)" 
} 

第一次運行時總是好的 - 我可以獲取當前時間和顯示它正確。但隨後的運行從未成功。輸出流不能寫入任何字節。而輸入流得到讀取時出現以下錯誤:

ErrorOccurred:可選( 「錯誤域= NSPOSIXErrorDomain碼= 32 \」 破管\ 「」)

我試着尋找很長一段時間卻找不到解決辦法。任何幫助將非常感激。

回答

0

看起來像NSInputStream和NSOutputStream不應該在流完成後重新使用。我的代碼更改爲以下解決此問題:

func start(ipAddress ipAddress: String) { 
     self.conn = Connection(serverAddress: ipAddress) 
     self.sendTimer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "getTimeAndUpdateUI", userInfo: nil, repeats: true) 
     NSRunLoop.currentRunLoop().addTimer(self.sendTimer!, forMode: NSDefaultRunLoopMode) 
} 

func getTimeAndUpdateUI() { 
    self.conn!.connect() 
    let time = self.conn!.receive() 
    self.timeLabel.text = "Current time is \(time)" 
    self.conn!.disconnect() 
} 

每一次iOS的民調信息的服務器,它再現NSInputStream和NSOutputStream的一個實例。

任何改善建議是值得歡迎的。謝謝。