+7  A: 

Since CFWriteStream is toll-free bridged to NSOutputStream you can use CFStreamCreatePairWithSocketToHost to get your stream pair:

CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)host, port, &readStream, &writeStream);
if (readStream && writeStream) {
    CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
    CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);

    inputStream = (NSInputStream *)readStream;
    [inputStream retain];
    [inputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];

    outputStream = (NSOutputStream *)writeStream;
    [outputStream retain];
    [outputStream setDelegate:self];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream open];
}

if (readStream)
    CFRelease(readStream);

if (writeStream)
    CFRelease(writeStream);
Matt Stevens
Thanks. And one more question:'kCFStreamPropertyShouldCloseNativeSocket' cannot be found either. Should I use 'kCFStreamPropertySocketNativeHandle' instead or just don't set property for CFWriteStream?
iPhoney
It's there, you may need to #include <CFNetwork/CFSocketStream.h>
Matt Stevens
+1  A: 

I was having the same problem, and your answer really helped me out.

Just one question - how to I implement Error checking (connectino refused, etc..)?

I have tried this code using IP Addresses such as "192.168.0." and "192.168.0.12342456" and everything seems to connect, regardless of the horribly malformed addresses. How do I catch a case where someone enters the wrong IP Address?

-(IBAction)tryConnection{   
    CFReadStreamRef readStream = NULL;
    CFWriteStreamRef writeStream = NULL;
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)settings.masterLocation, [settings.masterPort intValue], &readStream, &writeStream);
    if (readStream && writeStream) {
        CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
        CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);

        iStream = (NSInputStream *)readStream;
        [iStream retain];
        [iStream setDelegate:self];
        [iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [iStream open];

        oStream = (NSOutputStream *)writeStream;
        [oStream retain];
        [oStream setDelegate:self];
        [oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [oStream open];
        if (iStream && oStream)  
            testLabel.title=@"Success";
        else
            testLabel.title=@"Failed!";  
    }
    if (readStream) CFRelease(readStream);
    if (writeStream) CFRelease(writeStream);
} else {
    testLabel.title=@"Failed!";
}
Dutchie432
You can use: -(void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode. And handle error when eventCode is NSStreamEventErrorOccurred.
iPhoney
The NSOutputStream can still be open even if you use a wrong url.
iPhoney
Oh, good lord - I was handling it already from before, when I was using NSHost. I was wondering why the program was handling the bad IP's so gracefully :)
Dutchie432
A: 

Take a look here

http://vfxwarriors.blogspot.com/2009/06/thestream.html

It would be great if you could expand this into a full, minimal working example with an iPhone app.
blackkettle
A: 

I am developing an app in which a socket connection is made similarly as shown above, when the connection is established i send a request and i get a response.

In response i get a IP and Port of another server to which i need to make a socket connection.

before making a socket connection to the new IP and Port, I need to close the previous socket connection. Closing the previous connection is handled perfectly the addresses are getting nulled but when i am opening the connection for new IP and port i get an exception that previous connection is already open

sumit
A: 

Can any one tell me how to open another socket connection by closing the previous socket connection

sumit
A: 

The code below works, however, how do I set the IP adres to the device I want to connect to?

  • (IBAction)searchForSite:(id)sender { NSString *urlStr = [sender stringValue]; if (![urlStr isEqualToString:@""]) { NSURL *website = [NSURL URLWithString:urlStr]; if (!website) { NSLog(@"%@ is not a valid URL"); return; }

    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)[website host], 80, &readStream, &writeStream);
    
    
    NSInputStream *inputStream = (NSInputStream *)readStream;
    NSOutputStream *outputStream = (NSOutputStream *)writeStream;
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream open];
    [outputStream open];
    

    } }

Timo den Hartog