Skip to content

Instantly share code, notes, and snippets.

@rjungemann
Created June 21, 2010 00:45
Show Gist options
  • Save rjungemann/446256 to your computer and use it in GitHub Desktop.
Save rjungemann/446256 to your computer and use it in GitHub Desktop.
How to open a TCP socket in Objective-C
#import <Foundation/Foundation.h>
@interface Communicator : NSObject <NSStreamDelegate> {
@public
NSString *host;
int port;
}
- (void)setup;
- (void)open;
- (void)close;
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event;
- (void)readIn:(NSString *)s;
- (void)writeOut:(NSString *)s;
@end
#import "Communicator.h"
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
NSInputStream *inputStream;
NSOutputStream *outputStream;
@implementation Communicator
- (void)setup {
NSURL *url = [NSURL URLWithString:host];
NSLog(@"Setting up connection to %@ : %i", [url absoluteString], port);
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)[url host], port, &readStream, &writeStream);
if(!CFWriteStreamOpen(writeStream)) {
NSLog(@"Error, writeStream not open");
return;
}
[self open];
NSLog(@"Status of outputStream: %i", [outputStream streamStatus]);
return;
}
- (void)open {
NSLog(@"Opening streams.");
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
[inputStream retain];
[outputStream retain];
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
- (void)close {
NSLog(@"Closing streams.");
[inputStream close];
[outputStream close];
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream setDelegate:nil];
[outputStream setDelegate:nil];
[inputStream release];
[outputStream release];
inputStream = nil;
outputStream = nil;
}
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event {
NSLog(@"Stream triggered.");
switch(event) {
case NSStreamEventHasSpaceAvailable: {
if(stream == outputStream) {
NSLog(@"outputStream is ready.");
}
break;
}
case NSStreamEventHasBytesAvailable: {
if(stream == inputStream) {
NSLog(@"inputStream is ready.");
uint8_t buf[1024];
unsigned int len = 0;
len = [inputStream read:buf maxLength:1024];
if(len > 0) {
NSMutableData* data=[[NSMutableData alloc] initWithLength:0];
[data appendBytes: (const void *)buf length:len];
NSString *s = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
[self readIn:s];
[data release];
}
}
break;
}
default: {
NSLog(@"Stream is sending an Event: %i", event);
break;
}
}
}
- (void)readIn:(NSString *)s {
NSLog(@"Reading in the following:");
NSLog(@"%@", s);
}
- (void)writeOut:(NSString *)s {
uint8_t *buf = (uint8_t *)[s UTF8String];
[outputStream write:buf maxLength:strlen((char *)buf)];
NSLog(@"Writing out the following:");
NSLog(@"%@", s);
}
@end
#import <Foundation/Foundation.h>
#import "Communicator.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Communicator *c = [[Communicator alloc] init];
c->host = @"http://127.0.0.1";
c->port = 6789;
[c setup];
[c open];
[pool drain];
return 0;
}
@dkressaty
Copy link

Axelpanning: In recent versions of iOS Apple has started rigidly enforcing privacy and permissions. And, here's the real rub, calls to services have been known to die silently, without throwing an error. Makes it tough to troubleshoot. It took me nearly a week to find out that my calls to Location Services were being ignored. Most likely there's a key that you'll need to add to the info.plist file AND make a call to iOS to ask the user for permission to access network services or some such thing. As I work through this example, if I find the exact combination, I'll post it here.

@yuktikapahwa
Copy link

Hi,
I am able to open a stream with the server ,but how can i write a message in the output stream ?
I am sorry but I am completely new to objective C.
Any help would be appreciated
I want to write any message-May be "hello World"

@nareshpareek
Copy link

hi @rjungemann
Thank you for simple code. Could you help me write something similar in Swift 3.0

@krunal13257
Copy link

Amazing example works well.... I am able to send data to other device but when i write to output stream data is getting received on other side when i close my app, please help what could be the mistake?

@bibinmathew3720
Copy link

Not able to send data in ios 11

@vikrantrajput
Copy link

Code is working well means I am getting streaming data in handleEvent delegate method but when app is in foreground mean when I lock my iPhone the connection getting break TCP connection break. So how I can handle this problem. I got stuck on this point.
Thanks

@omy2301
Copy link

omy2301 commented Feb 23, 2018

[data appendBytes: (const void *)buf length:len];

I got crash here

@limtingfei
Copy link

For those who successfully streamed, what is the suitable stream and event argument to pass in in order to start Listening?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment