Ios Simple Tcp Connection Example

iOS simple TCP connection example

SocketConnectionVC.h

#import <UIKit/UIKit.h>

@interface SocketConnectionVC : UIViewController<NSStreamDelegate>
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;

NSInputStream *inputStream;
NSOutputStream *outputStream;

NSMutableArray *messages;
}

@property (weak, nonatomic) IBOutlet UITextField *ipAddressText;
@property (weak, nonatomic) IBOutlet UITextField *portText;
@property (weak, nonatomic) IBOutlet UITextField *dataToSendText;
@property (weak, nonatomic) IBOutlet UITextView *dataRecievedTextView;
@property (weak, nonatomic) IBOutlet UILabel *connectedLabel;


@end

SocketConnectionVC.m

#import "SocketConnectionVC.h"

@interface SocketConnectionVC ()

@end

@implementation SocketConnectionVC

- (void)viewDidLoad {
[super viewDidLoad];

_connectedLabel.text = @"Disconnected";
}

- (IBAction) sendMessage {

NSString *response = [NSString stringWithFormat:@"msg:%@", _dataToSendText.text];
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];

}

- (void) messageReceived:(NSString *)message {

[messages addObject:message];

_dataRecievedTextView.text = message;
NSLog(@"%@", message);
}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {

NSLog(@"stream event %lu", streamEvent);

switch (streamEvent) {

case NSStreamEventOpenCompleted:
NSLog(@"Stream opened");
_connectedLabel.text = @"Connected";
break;
case NSStreamEventHasBytesAvailable:

if (theStream == inputStream)
{
uint8_t buffer[1024];
NSInteger len;

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);
[self messageReceived:output];
}
}
}
}
break;

case NSStreamEventHasSpaceAvailable:
NSLog(@"Stream has space available now");
break;

case NSStreamEventErrorOccurred:
NSLog(@"%@",[theStream streamError].localizedDescription);
break;

case NSStreamEventEndEncountered:

[theStream close];
[theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
_connectedLabel.text = @"Disconnected";
NSLog(@"close stream");
break;
default:
NSLog(@"Unknown event");
}

}

- (IBAction)connectToServer:(id)sender {

NSLog(@"Setting up connection to %@ : %i", _ipAddressText.text, [_portText.text intValue]);
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef) _ipAddressText.text, [_portText.text intValue], &readStream, &writeStream);

messages = [[NSMutableArray alloc] init];

[self open];
}

- (IBAction)disconnect:(id)sender {

[self close];
}

- (void)open {

NSLog(@"Opening streams.");

outputStream = (__bridge NSOutputStream *)writeStream;
inputStream = (__bridge NSInputStream *)readStream;

[outputStream setDelegate:self];
[inputStream setDelegate:self];

[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[outputStream open];
[inputStream open];

_connectedLabel.text = @"Connected";
}

- (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 = nil;
outputStream = nil;

_connectedLabel.text = @"Disconnected";
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

snapshot for ui of this SocketConnectionVC
Sample Image

and Follow these steps

1- input the ip on ipAdress textfield
2- input the port on port textfield
3- press connect button
4- (make sure the ip address and port is correct and the open of stream is fine. you can show the status of stream on console of Xcode)
5- input data to send to server
6- press send button
7- you can show the received message from server on the text view above connect button

iPhone TCP/IP Socket Server/Client Program

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.

TCP Socket using Swift

You can use SwiftSocket available on github written by swiftsocket

it has a class TCPClient

IOS to Android and vice versa TCP server client connection using sockets

I was able to send messages after i opened the output stream (NSOutputStream) the only problem i am facing is android receives messages only when i close my output stream can any one tell me where i am going wrong

the client code for android is as follows

package com.example.remoteapp;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import android.util.Log;



public class TCPClient {

private String serverMessage;
/**
* Specify the Server Ip Address here. Whereas our Socket Server is started.
* */
//public static final String SERVERIP = "192.168.43.1"; // fixed IP address for hotspot
public static final String SERVERIP = "192.168.1.44"; //computer ip address

//public static final int SERVERPORT = 4321;
public static final int SERVERPORT = 57917;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;

private PrintWriter out = null;
private BufferedReader in = null;

/**
* Constructor of the class. OnMessagedReceived listens for the messages received from server
*/
public TCPClient(final OnMessageReceived listener)
{
mMessageListener = listener;
}

/**
* Sends the message entered by client to the server
* @param message text entered by client
*/
public void sendMessage(String message){
if (out != null && !out.checkError()) {
System.out.println("message: "+ message);
// out.println(message);
// out.flush();
}
}

public void stopClient(){
mRun = false;
}

public void run() {

mRun = true;

try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVERIP);

Log.e("TCP SI Client", "SI: Connecting...");

//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVERPORT);
try {

//send the message to the server
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

Log.e("TCP SI Client", "SI: Sent.");

Log.e("TCP SI Client", "SI: Done.");

sendMessage("initial message");
//receive the message which the server sends back
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

//in this while the client listens for the messages sent by the server
while (mRun) {
serverMessage = in.readLine();

if (serverMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(serverMessage);
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");
}
serverMessage = null;
}
}
catch (Exception e)
{
Log.e("TCP SI Error", "SI: Error", e);
e.printStackTrace();
}
finally
{
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
socket.close();
}

} catch (Exception e) {

Log.e("TCP SI Error", "SI: Error", e);

}

}

//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
//class at on asynckTask doInBackground
public interface OnMessageReceived {
public void messageReceived(String message);
}
}

iOS: read and write in a socket (tcp connection)

Don't do it on main thread. As your user case is simple, I write a simple example. I don't test it by the way...

int sock = socket(AF_INET, SOCK_STREAM, 0) ;
struct sockaddr_in server_addr ;
bzero(&server_addr, sizeof(server_addr)) ;
server_addr.sin_port = htons(1025) ;
server_addr.sin_addr.s_addr = inet_addr("192.168.1.5") ;
server_addr.sin_family = AF_INET ;

int i = connect(sock, (const struct sockaddr *)&server_addr, sizeof(server_addr)) ;
if (i >= 0) {
char writeBuf[17] = "12345678901234567" ;
long w = write(sock, writeBuf, 17) ;
if (w > 0) {
char bufferRead[1024] ;
long r = read(sock, bufferRead, sizeof(bufferRead)) ;
if (r > 0) {
// success
}
}
}
close(sock) ;

How to create TCP IP Server using Objective-C on iOS

There are better native alternatives to CocoaAsyncSocket now, namely Apple's Network Framework.

Here is some nice sample code for a simple TCP client & server using the nw functions:
https://developer.apple.com/documentation/network/implementing_netcat_with_network_framework

iphone tcp connection - more than one socket is being created

Your logs indicate that you are either getting two viewDidLoad messages or you are getting getting one each on two different views. You don't mention changing view at all, so that would seem to rule out the latter, which leaves the former.

Try placing a breakpoint in viewDidLoad and see whether the ViewController instance (self) is the same both times. If it is the same, you'll need to look at the stack crawl and see where the second call is coming from, because hat would usually indicate a reload after a low memory event, which shouldn't happen on modern devices. If the ViewController instance is different, then you need to see why a second ViewController is being allocated. Again, the stack trace could help as well as creating an init method and setting a breakpoint on it.



Related Topics



Leave a reply



Submit