2009-04-11 14 views
9

Ich habe einen Daemon auf einem Server ausgeführt, der auf einen TCP/IP-Port verriegelt ist. Ich bin auf der Suche, ob es derzeit Unterstützung für iPhone/Cocoa-Touch-Frameworks gibt, die einen netten OO-Wrapper zum Sprechen über einen IP-Socket an den Daemon liefern. Ich muss in der Lage sein, den Daemon interaktiv mit Befehlen abzufragen und zurück Informationen zu erhalten.Cocoa-Touch-Framework für das Sprechen mit einem TCP-Socket?

Wenn es keine OO-Wrapper für solch eine Aufgabe gibt, was ist die nächstbeste Wette?

Antwort

6

Grob gesagt, den Stapel Sie steigen:

  • BSD-Sockets
  • CFSocket
  • CFReadStream/CFWriteStream/NSInputStream/NSOutputStream
  • CFHTTPStream
  • NSURLConnection

Klingt wie du willst CFSocket, oder möglicherweise CFStream.

15

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

Dies ist, was Sie wollen.

+0

Ist es jetzt veraltet? Ich habe versucht, es in Xcode 4 zu verwenden, bekam aber 17 Probleme, nur indem ich die Klassen im Projekt hinzufügte. – Rihards

+2

@Richards Nein, es ist immer noch aktiv bei https://github.com/robihanson/CocoaAsyncSocket gepflegt –

+0

Danke, sieht aus wie jetzt zu arbeiten. – Rihards

13

Hier ist ein Beispielcode aus dem zuvor erwähnten Code AsyncSocket, den ich in eine Klasse namens SocketCommunicationManager geändert habe.

ein paar Dinge zu beachten:

  • Unsere Nachrichten mit Zeilenumbrüchen begrenzt werden so (\ n), wenn Daten aus der Steckdose zu lesen ich musste sicherstellen, dass die richtige Konstante aus der AsyncSocket Klasse verwenden (LFData in unserem Fall). AsyncSocket stellt außerdem CRLFData, CRData und ZeroData als vordefinierte Nachrichtentrennzeichen zur Verfügung.
  • Ich richte den SocketCommunicationManager so ein, dass ich immer auf eine eingehende Nachricht warte, nachdem ich eine vorherige Nachricht empfangen und bearbeitet habe. Um das zu erreichen, benutzte ich die (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag Methode. Diese Methode wartet, bis Daten in den Socket geschrieben wurden, liest bis zum angegebenen Begrenzer und ruft anschließend die Delegate-Methode (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
  • auf. Der SocketCommunicationManager verwendet NSNotificationCenter, um alle vom Socket empfangenen Nachrichten zu veröffentlichen. Diese Nachrichten erhalten den Namen kNotification. Die Nachricht wird mithilfe des Schlüssels kNotificationMessage in das userInfo-Wörterbuch geschrieben.
  • Alles, was vom Socket gelesen wird, ist in ein NSData-Objekt eingeschlossen, so dass Sie diese Daten nach dem Empfang dekodieren müssen.

Hier ist der 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 
Verwandte Themen