Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa-Touch framework for speaking to a TCP socket? [closed]

I have a daemon running on a server that's latched onto a TCP/IP port. I'm looking to see if there's currently any support iPhone/Cocoa-touch frameworks that gives a nice OO wrapper for speaking to the daemon over an IP socket. I need to be able to interactively query the daemon with commands and retrieve back information.

If there isn't any OO wrappers for such a task, what's the next best bet?

like image 585
Coocoo4Cocoa Avatar asked Apr 11 '09 15:04

Coocoo4Cocoa


2 Answers

http://code.google.com/p/cocoaasyncsocket/

This is what you want.

like image 135
Genericrich Avatar answered Oct 07 '22 16:10

Genericrich


Here is some sample code from the previously mentioned AsyncSocket code that I modified into a class called SocketCommunicationManager.

A few things to note:

  • Our messages are being delimited with newline characters (\n) so when reading data from the socket I had to make sure to use the right constant from the AsyncSocket class (LFData in our case). AsyncSocket also provides CRLFData, CRData, and ZeroData as predefined message delimiters.
  • I set up the SocketCommunicationManager to always wait for an incoming message after I received and acted on a previous one. To accomplish that I used the (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag method. This method will wait until data is written to the socket, read up until the specified delimiter, and then call the delegate method (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
  • The SocketCommunicationManager uses NSNotificationCenter to publish any messages received from the socket. These messages are named kNotification and the message is put into the userInfo dictionary using the kNotificationMessage key.
  • Everything read from the socket is wrapped in an NSData object, so you'll have to decode that data after it is received.

Here's the code:

#import <Foundation/Foundation.h>

extern NSString * const kNotification;
extern NSString * const kNotificationMessage;

@class AsyncSocket;

@interface SocketCommunicationManager : NSObject {
    AsyncSocket *socket;
    BOOL isRunning;
    NSNotificationCenter* notificationCenter;
}

@property (readwrite, assign) BOOL isRunning;

- (void)connectToHost:(NSString *)hostName onPort:(int)port;
- (void)sendMessage:(NSString *)message;
- (void)disconnect;

@end


#import "SocketCommunicationManager.h"
#import "AsyncSocket.h"

NSString * const kNotification = @"kNotification";
NSString * const kNotificationMessage = @"kNotificationMessage";

@implementation SocketCommunicationManager

@synthesize isRunning;

- (id) init {
    if (!(self = [super init]))
        return nil;

    socket = [[AsyncSocket alloc] initWithDelegate:self];
    [self setIsRunning:NO];
    notificationCenter = [NSNotificationCenter defaultCenter];

    return self;
}

- (void)connectToHost:(NSString *)hostName onPort:(int)port {
    if (![self isRunning]) {
        if (port < 0 || port > 65535)
            port = 0;

        NSError *error = nil;
        if (![socket connectToHost:hostName onPort:port error:&error]) {
            NSLog(@"Error connecting to server: %@", error);
            return;
        }

        [self setIsRunning:YES];
    } else {
        [socket disconnect];
        [self setIsRunning:false];
    }
}

- (void)disconnect {
    [socket disconnect];
}

- (void)dealloc {
    [super dealloc];
    [socket disconnect];
    [socket dealloc];
}

- (void)sendMessage:(NSString *)message {
    NSString *terminatedMessage = [message stringByAppendingString:@"\r\n"];
    NSData *terminatedMessageData = [terminatedMessage dataUsingEncoding:NSASCIIStringEncoding];
    [socket writeData:terminatedMessageData withTimeout:-1 tag:0];
}

#pragma mark AsyncSocket Delegate

- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
    NSLog(@"Connected to server %@:%hu", host, port);
    [sock readDataToData:[AsyncSocket LFData] withTimeout:-1 tag:0];
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSData *truncatedData = [data subdataWithRange:NSMakeRange(0, [data length] - 1)];
    NSString *message = [[[NSString alloc] initWithData:truncatedData encoding:NSASCIIStringEncoding] autorelease];

    if (message)
        NSLog(@"%@", message);
    else
        NSLog(@"Error converting received data into UTF-8 String");

    NSDictionary *userInfo = [NSDictionary dictionaryWithObject:message forKey:kNotificationMessage];
    [notificationCenter postNotificationName:kNotification object:self userInfo:userInfo];

    [sock readDataToData:[AsyncSocket LFData] withTimeout:-1 tag:0];
}

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag {
    [sock readDataToData:[AsyncSocket LFData] withTimeout:-1 tag:0];
}

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err {
    NSLog(@"Client Disconnected: %@:%hu", [sock connectedHost], [sock connectedPort]);
}


@end
like image 34
Michael Fey Avatar answered Oct 07 '22 15:10

Michael Fey