I am desperately trying to figure out how to detect errors when opening TCP streams using NSStream +getStreamsToHost/CFStreamCreatePairWithSocket(). If I do this:
NSInputStream* input = nil;
NSOutputStream* output = nil;
[NSStream getStreamstoHost:[NSHost hostWithName:@"localhost"] port:80 inputStream:&input outputStream:&output];
NSError* error1 = [input streamError];
assert(error1 == nil);
NSStreamStatus status1 = [input streamStatus];
[input open];
NSError* error2 = [input streamError];
assert(error2 == nil);
NSStreamStatus status2 = [input streamStatus];
status1 is NSStreamStatusNotOpen, which is expected. error1 is nil. error2 is also nil, and status2 is NSStreamStatusOpening. If I telnet to the same address, I get connection refused – there is nothing listening on port 80. If I try to connect to some nonsensical address, such as yaddayadda, I get nil streams.
How do I handle errors properly? No example anywhere seems to handle error conditions, and the docs don’t say anything about it, other than the streams may be nil. I’m stumped. Don’t tell me I have to run the connection through a run loop, just to get proper error handling…?
I know there’s always the possibility of using good ol’ BSD sockets, but the docs warns against that, as some high level networking features may fail (auto connections over VPN, and similar stuff).
What you need to do is either poll for the status using the
streamStatusmethod on the input stream, or schedule the streams for events in a run loop. To better provide error information about erroneous host names, it’s better to resolve the name before hand using eitherNSHostorCFHost.