2009-04-11 13 views
9

Possiedo un daemon in esecuzione su un server bloccato su una porta TCP/IP. Sto cercando di vedere se attualmente sono supportati i framework iPhone/Cocoa-touch che forniscono un bel wrapper OO per parlare al daemon su un socket IP. Devo essere in grado di interrogare interattivamente il daemon con i comandi e recuperare informazioni.Quadro Cocoa-Touch per parlare con un socket TCP?

Se non ci sono wrapper OO per tale compito, qual è la prossima migliore scommessa?

risposta

6

In parole povere, risalendo la pila si dispone:

  • socket BSD
  • CFSocket
  • CFReadStream/CFWriteStream/NSInputStream/NSOutputStream
  • CFHTTPStream
  • NSURLConnection

Sembra che tu voglia CFSocket, o forse CFStream.

15

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

Questo è ciò che si desidera.

+0

È obsoleto? Stavo cercando di usarlo in Xcode 4, ma ho avuto 17 problemi solo aggiungendo le classi nel progetto. – Rihards

+2

@Richards No, è ancora mantenuto attivamente su https://github.com/robbiehanson/CocoaAsyncSocket –

+0

Grazie, sembra che funzioni adesso. – Rihards

13

Ecco alcuni esempi di codice dal codice AsyncSocket precedentemente specificato che ho modificato in una classe denominata SocketCommunicationManager.

Alcune cose da notare:

  • nostri messaggi vengono delimitati con caratteri di nuova riga (\ n) in modo che quando la lettura dei dati dal socket ho dovuto fare in modo di utilizzare il proprio costante dalla classe AsyncSocket (LFData nel nostro caso). AsyncSocket fornisce anche CRLFData, CRData e ZeroData come delimitatori di messaggi predefiniti.
  • Ho impostato SocketCommunicationManager in modo che attenda sempre un messaggio in arrivo dopo aver ricevuto e eseguito una precedente. Per realizzare ciò ho usato il metodo (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag. Questo metodo attenderà che i dati vengano scritti nel socket, letto fino al delimitatore specificato e quindi chiama il metodo delegato (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
  • SocketCommunicationManager utilizza NSNotificationCenter per pubblicare tutti i messaggi ricevuti dal socket. Questi messaggi sono denominati kNotification e il messaggio viene inserito nel dizionario userInfo utilizzando la chiave kNotificationMessage.
  • Tutto ciò che viene letto dal socket è racchiuso in un oggetto NSData, quindi sarà necessario decodificare i dati dopo averli ricevuti.

Ecco il codice:

#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 
Problemi correlati