Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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;
}
@metuceng

This comment has been minimized.

Copy link

commented Aug 13, 2012

thanks for the code. but i got an error while running. i tried to write something to outputstream but it says "stream is not open for writing".
at the same time i checked the streamstatus and it returns 0. why could it be

@abusivewings

This comment has been minimized.

Copy link

commented May 5, 2013

How do i receive data?

@trfd

This comment has been minimized.

Copy link

commented May 22, 2013

I have quite the same implementation as yours on my iOS app, but the messages written in the output stream are sent to my server only when the app is killed (stopped by xcode or killed in the iOS dock).
Are your messages sent right after the write:maxLength: call ?

Edit: Problem solved, apparently the message must finish with a "\n" to flush the output stream !

@CraigMetcalfe

This comment has been minimized.

Copy link

commented Sep 4, 2013

@traff589: sometimes I believe it requires "\r\n", that is just to be extra safe in case newline by itself is not working.

Anyhow, if your project uses ARC, just remove references to [retain] and [release], along with NSAutoReleasePool

@AshrafTawfeeq

This comment has been minimized.

Copy link

commented Sep 18, 2014

Craig's answer did all the magic.

@jp-dubey07

This comment has been minimized.

Copy link

commented Oct 7, 2014

I'm getting error : Cast of objective-C pointer type 'NSString' to C pointer type 'CFStringtRef'(aka 'const struct_CFString *') requires a bridged cast.
What should be fix?

@jp-dubey07

This comment has been minimized.

Copy link

commented Oct 7, 2014

Also, I want to sent dictionary along with request while opening the socket. Based on dictionary content I should get response from server. In Java below code is used :

printWriter.println("search^"+ asNoOfRecords + "|5|"+ asReturnType +"|" + asPageNo + "^" + asSearchCriteria + "^1234567abcdefg");

What changes need to be carried out in code to implement this?

@hafiz-mohsin-confiz

This comment has been minimized.

Copy link

commented Dec 12, 2014

how to communicate the client with server ?
can give some demo about client its helps alot people.

@axelpanning

This comment has been minimized.

Copy link

commented Jun 11, 2015

For me the (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event is never called. I used exactly the files you put here. I can write data to a server but i never get response. I encountered several people in the web have similar issues with that event and receiving data.

What can I do wrong here?

@dkressaty

This comment has been minimized.

Copy link

commented Feb 21, 2016

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

This comment has been minimized.

Copy link

commented May 18, 2016

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

This comment has been minimized.

Copy link

commented Sep 8, 2016

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

@krunal13257

This comment has been minimized.

Copy link

commented Sep 23, 2016

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

This comment has been minimized.

Copy link

commented Dec 6, 2017

Not able to send data in ios 11

@vikrantrajput

This comment has been minimized.

Copy link

commented Dec 13, 2017

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

This comment has been minimized.

Copy link

commented Feb 23, 2018

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

I got crash here

@limtingfei

This comment has been minimized.

Copy link

commented Jan 16, 2019

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
You can’t perform that action at this time.