Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone TCP/IP Socket Server/Client Program

Tags:

I have read a lot of questions regarding this subject on this website however they didn't quiet answer my question. If you can't be ### about my goal or background skip to the question.

My Goal

Is to build a server that can run on Mac OS X 10.4+ and later, port it to Windows XP/Vista (no idea how to do that yet, but that's a problem for later).

Then let the iPhone be the client that is able to see the computer names that are running the server (through WiFi). The user of the iPhone can then select the computer name to connect to the server on that computer.

After that they can send simple text messages to each other. For example, the iPhone sends 'Knock Knock' and the server responds 'Who is there?'. Or a simple client: 'Ping', server responds 'Pong' will do just fine.

Background

I have worked with sockets in the past, but only in Visual Basic 6 with the WINSOCKET.dll it was very easy to create a TCP/IP server.

server.host = localhost; server.port = 12203; server.listen();  

With the client I only needed to do the following to connect.

client.connect(localhost, 12203); 

There were some callbacks available like connect, close, dataArrival, etc. which I could use to do anything I want.

Perhaps for the iPhone there are libraries written for it, but is it that hard to create this simple application yourself? After doing some research I understand that I have to look in the area of CFNetwork, CFHost, CFSocket, CFStream.

Question

Is there anyone that could guide me to a tutorial or post the code where you have two buttons on the iPhone. [ Start Server ] and [ Connect to Server] where the first will start a TCP/IP server on a certain port and the second connects to it.

After a connection has been made maybe also the code to send a simple 'Ping'-message to the server after the server receives this responds with a 'Pong'-message to the client.

That would really be helpful. But maybe I am asking for to much here.

like image 500
Mark Avatar asked Sep 17 '09 10:09

Mark


People also ask

What is socket programming in IOS?

Socket.IO is a JavaScript library for real-time web applications(Instant messengers, Push Notifications, Online Gaming). Sockets have traditionally been the solution around which most real-time systems are architected, providing a bi-directional communication channel between a client and a server.

What is TCP IP server socket and client socket?

TCP/IP sockets are used to implement reliable, bidirectional, persistent, point-to-point, stream-based connections between hosts on the Internet. TCP/IP Client Sockets. TCP/IP sockets are used to implement reliable, bidirectional, persistent, point-to-point, stream-based connections between hosts on the Internet.

How client and server communicate using TCP sockets?

TCP sockets are used for communication between a server and a client process. The server's code runs first, which opens a port and listens for incoming connection requests from clients. Once a client connects to the same (server) port, the client or server may send a message.

How do I program a TCP IP socket?

Steps to create a client using TCP/IP APICreate a socket with the socket() system call. Initialize the socket address structure as per the server and connect the socket to the address of the server using the connect() system call. Receive and send the data using the recv() and send().


2 Answers

this tutorial to create a chat sample app works very well and is pretty straightforward (any iphone noob, like me, can make it work, EVEN IN SIMULATOR MODE it connects to external socket server).

i adapted it to talk my socket server and it works like a charm. this is test code, so there's no real concern with loose ends. it only sends one message (your logon id) and receives an answer back, which it shows in the console.

// //  ViewController.m //  zdelSocketTest01a // //  #import "ViewController.h"    @implementation ViewController @synthesize inputNameField; @synthesize joinView;  - (void)initNetworkCommunication {      uint portNo = 5555;     CFReadStreamRef readStream;     CFWriteStreamRef writeStream;     CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"227.3.4.56", portNo, &readStream, &writeStream);     inputStream = (__bridge NSInputStream *)readStream;     outputStream = (__bridge NSOutputStream *)writeStream;      [inputStream setDelegate:self];     [outputStream setDelegate:self];      [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];     [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];     [inputStream open];     [outputStream open]; }  - (void)didReceiveMemoryWarning {     [super didReceiveMemoryWarning];     // Release any cached data, images, etc that aren't in use. }  #pragma mark - View lifecycle  - (void)viewDidLoad {     [super viewDidLoad];     // Do any additional setup after loading the view, typically from a nib.     [self initNetworkCommunication];     messages = [[NSMutableArray alloc] init]; }  - (void)viewDidUnload {     [self setInputNameField:nil];     [self setJoinView:nil];     [self setJoinView:nil];     [super viewDidUnload];     // Release any retained subviews of the main view.     // e.g. self.myOutlet = nil; }  - (void)viewWillAppear:(BOOL)animated {     [super viewWillAppear:animated]; }  - (void)viewDidAppear:(BOOL)animated {     [super viewDidAppear:animated]; }  - (void)viewWillDisappear:(BOOL)animated {     [super viewWillDisappear:animated]; }  - (void)viewDidDisappear:(BOOL)animated {     [super viewDidDisappear:animated]; }  - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {     // Return YES for supported orientations     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); }  - (IBAction)joinChat:(id)sender {      NSString *response  = [NSString stringWithFormat:@"logon,%@", inputNameField.text];     NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];     [outputStream write:[data bytes] maxLength:[data length]];  } /*  - (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {  NSLog(@"stream event %i", streamEvent);  }  */  - (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {     typedef enum {         NSStreamEventNone = 0,         NSStreamEventOpenCompleted = 1 << 0,         NSStreamEventHasBytesAvailable = 1 << 1,         NSStreamEventHasSpaceAvailable = 1 << 2,         NSStreamEventErrorOccurred = 1 << 3,         NSStreamEventEndEncountered = 1 << 4     };     uint8_t buffer[1024];     int len;      switch (streamEvent) {          case NSStreamEventOpenCompleted:             NSLog(@"Stream opened now");             break;         case NSStreamEventHasBytesAvailable:             NSLog(@"has bytes");             if (theStream == inputStream) {                 while ([inputStream hasBytesAvailable]) {                     len = [inputStream read:buffer maxLength:sizeof(buffer)];                     if (len > 0) {                          NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];                          if (nil != output) {                             NSLog(@"server said: %@", output);                         }                     }                 }             } else {                 NSLog(@"it is NOT theStream == inputStream");             }             break;         case NSStreamEventHasSpaceAvailable:             NSLog(@"Stream has space available now");             break;           case NSStreamEventErrorOccurred:             NSLog(@"Can not connect to the host!");             break;           case NSStreamEventEndEncountered:              [theStream close];             [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];              break;          default:             NSLog(@"Unknown event %i", streamEvent);     }  } /*  - (void) messageReceived:(NSString *)message {   [messages addObject:message];  [self.tView reloadData];   }  */  @end 

your ViewController.h file would contain

#import <UIKit/UIKit.h>  @interface ViewController : UIViewController <NSStreamDelegate> @property (weak, nonatomic) IBOutlet UITextField *inputNameField; @property (weak, nonatomic) IBOutlet UIView *joinView; - (IBAction)joinChat:(id)sender;   @end NSInputStream *inputStream; NSOutputStream *outputStream; NSMutableArray * messages; 

NOOBS ONLY: you must link your button and text field by pressing CONTROL and dragging the object into the code window. when you do that, the properties above will automatically be created. check this video tutorial if you are stumped

NOOBS ONLY 2: this socket will output in the CONSOLE PANE of XCODE. on the upper right hand corner of your xcode window, click HIDE OR SHOW THE DEBUG AREA (ask for help if necessary).

built and tested (simulator and device) on a macbook with 2GB memory, using xcode 4.2 for snow leopard.

like image 82
tony gil Avatar answered Oct 21 '22 21:10

tony gil


I recommend the the following: Cocoa Async Socket

There's also a basic example project on the site to get you started. I've had good success working with that framework.

like image 31
Kongress Avatar answered Oct 21 '22 22:10

Kongress