2009-04-11 28 views
9

Tôi có một daemon đang chạy trên một máy chủ được gắn vào cổng TCP/IP. Tôi đang tìm xem liệu có bất kỳ khung hỗ trợ iPhone/Cocoa-touch nào hỗ trợ một trình bao bọc OO tốt đẹp để nói chuyện với daemon qua một ổ cắm IP. Tôi cần để có thể truy vấn tương tác daemon với các lệnh và lấy lại thông tin.Khuôn khổ Cocoa-Touch để nói với một ổ cắm TCP?

Nếu không có bất kỳ trình bao bọc OO nào cho tác vụ như vậy, cược nào tốt nhất tiếp theo?

Trả lời

6

Khoảng nói, đi lên ngăn xếp bạn có:

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

Có vẻ như bạn muốn CFSocket, hoặc có thể là CFStream.

15

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

Đây là những gì bạn muốn.

+0

Hiện đã lỗi thời chưa? Tôi đã cố gắng sử dụng nó trong Xcode 4, nhưng có như 17 vấn đề chỉ bằng cách thêm các lớp học trong dự án. – Rihards

+2

@Richards Không, nó vẫn được duy trì tích cực tại https://github.com/robbiehanson/CocoaAsyncSocket –

+0

Cảm ơn, có vẻ như đang hoạt động. – Rihards

13

Dưới đây là một số mã mẫu từ mã được đề cập trước đây AsyncSocket mà tôi đã sửa đổi thành một lớp có tên SocketCommunicationManager.

Một số điều cần lưu ý:

  • thông điệp của chúng tôi đang được phân định với các nhân vật xuống dòng (\ n) nên khi đọc dữ liệu từ các ổ cắm tôi phải đảm bảo sử dụng quyền liên tục từ lớp AsyncSocket (LFData trong trường hợp của chúng tôi). AsyncSocket cũng cung cấp CRLFData, CRData và ZeroData làm các dấu phân tách thư được xác định trước.
  • Tôi thiết lập SocketCommunicationManager để luôn đợi một tin nhắn gửi đến sau khi tôi nhận được và hành động trên tin nhắn trước đó. Để thực hiện điều đó, tôi đã sử dụng phương thức (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag. Phương pháp này sẽ đợi cho đến khi dữ liệu được ghi vào ổ cắm, đọc cho đến khi dấu phân cách được chỉ định và sau đó gọi phương thức ủy nhiệm (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
  • SocketCommunicationManager sử dụng NSNotificationCenter để xuất bản bất kỳ tin nhắn nào nhận được từ socket. Các thông báo này được đặt tên là kNotification và thông điệp được đưa vào từ điển userInfo bằng cách sử dụng khóa kNotificationMessage.
  • Mọi thứ được đọc từ ổ cắm được bọc trong một đối tượng NSData, vì vậy bạn sẽ phải giải mã dữ liệu đó sau khi nhận được.

Dưới đây là các mã:

#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 
Các vấn đề liên quan