How to check if my remote NSStream socket is open correctly

TL DR: How to check if my remote stream is opened correctly after calling NSStream.getStreamsToHostWithName(...) ?

My app is the iOS8 mobile app for quick work.

I use NSStream to input and output sockets from a remote server.

To connect to my server and open my stream, I use this code:

 func connect(host: String, port: Int) -> Bool { //clear the previous connection if existing (and update self.connected) disconnect() //updating the current connection self.host = host self.port = port //pairing NSstreams with remote connection NSStream.getStreamsToHostWithName(self.host!, port: self.port!, inputStream: &inputStream, outputStream: &outputStream) if (self.inputStream != nil && self.outputStream != nil) { //open streams self.inputStream?.open() self.outputStream?.open() } if self.outputStream?.streamError == nil && self.inputStream?.streamError == nil { println("SOK") //PROBLEM 1 } //error checking after opening streams // PROBLEM 2 if var inputStreamErr: CFError = CFReadStreamCopyError(self.inputStream)? { println("InputStream error : " + CFErrorCopyDescription(inputStreamErr)) } else if var outputStreamErr: CFError = CFWriteStreamCopyError(self.outputStream)? { println("OutStream error : " + CFErrorCopyDescription(outputStreamErr)) } else { //set the delegate to self self.inputStream?.delegate = self self.outputStream?.delegate = self self.connected = true } //return connection state return self.connected } 

My problem is in // PROBLEM 1 and // PROBLEM2.

At these points, I try to determine if my sockets are open correctly, but even if the server is not working, this code is still working, then the read and write operations are not performed. I would like to be able to determine if the connection was unsuccessful or not.

Perhaps I am doing it completely wrong, I do not understand how to check it.

+5
source share
1 answer

First of all, you should plan the thread on runloop :

 inputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode) outputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode) 

And in your code, it's too soon to check for an error. Since open() is asynchronous, you need to wait for the result using delegate . Here is a working example:

 import Foundation class Connection: NSObject, NSStreamDelegate { var host:String? var port:Int? var inputStream: NSInputStream? var outputStream: NSOutputStream? func connect(host: String, port: Int) { self.host = host self.port = port NSStream.getStreamsToHostWithName(host, port: port, inputStream: &inputStream, outputStream: &outputStream) if inputStream != nil && outputStream != nil { // Set delegate inputStream!.delegate = self outputStream!.delegate = self // Schedule inputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode) outputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode) print("Start open()") // Open! inputStream!.open() outputStream!.open() } } func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { if aStream === inputStream { switch eventCode { case NSStreamEvent.ErrorOccurred: print("input: ErrorOccurred: \(aStream.streamError?.description)") case NSStreamEvent.OpenCompleted: print("input: OpenCompleted") case NSStreamEvent.HasBytesAvailable: print("input: HasBytesAvailable") // Here you can `read()` from `inputStream` default: break } } else if aStream === outputStream { switch eventCode { case NSStreamEvent.ErrorOccurred: print("output: ErrorOccurred: \(aStream.streamError?.description)") case NSStreamEvent.OpenCompleted: print("output: OpenCompleted") case NSStreamEvent.HasSpaceAvailable: print("output: HasSpaceAvailable") // Here you can write() to `outputStream` default: break } } } } 

Then:

 let conn = Connection() conn.connect("www.example.com", port: 80) 
+28
source

Source: https://habr.com/ru/post/1213893/


All Articles