2009-06-12 29 views
5

IPC'yi, deneyimsiz olduğum UNIX etki alanı soketlerini kullanarak bir Kakao uygulamasında uygulamak istiyorum. Apple'ın CFLocalServer örnek projesini buldum, ama C dilinde yazılıyor ve oldukça karmaşık görünüyor (ve evet, çoğunu okudum).UNIX Etki Alanı Yuvaları ve Kakao

CFLocalServer'da gösterilen teknikler hâlâ en son teknolojide gösteriliyor mu, yoksa Nesne-C'de Kakao/Temel ile UNIX etki alanı soketlerini uygulama yolu var mı?

I (bu proje için büyük soyutlama sağlıklı bir miktarda temin) ve Mike Bean's Networking in Cocoa bazı çok ilişkili kod bulundu, ancak bu tüm Make mümkün olmamıştır NSSocketPort s ve NSFileHandle s ile oynuyorum Çalışın

Bunu daha önce yapan var mı?

cevap

4

ve bunlar oldukça iyi çalışır: Mac OSX o sağlıyor olmalı böylece BSD dayalı bir POSIX imsi bir işletim sistemidir. Sunucumun soketini kurdum (ama kendim oluşturmak için, başarıyla kod yazdım) ve istemcinin ona bağlanmasını sağladım.

şeyler öğrendim:

  • Sen sokete bir bağlantı oluşturmak için istemci tarafında connect() kullanmaya gerek yok

  • NSFileHandle

    içinde bağlantının her iki ucuna içine alabilirsiniz

  • İstemciyi ve sunucuyu yoksaymalısınız, SIGPIPE

  • sıfır uzunluklu veri ile geri çağrılırsınız, bu, soketin diğer ucundaki şeyin bağlantısının kesilmiş olduğu anlamına gelir (örn. sunucu/istemci çıkıldı). Bu durumda soket ucunu kapattığınızdan ve bıraktığınızdan emin olun - veriyi tekrar okumaya çalışmayın, ya da sadece başka bir sıfır uzunluklu okuma geri çağrısı alın (sonsuza kadar)

  • Sorumlusunuz soket genelinde gönderdiğiniz mesajlar sınırlayan ve montaj için

ben mutlu olurdu (bir ucunda gönderilen tek bir mesajı diğer ucunda birden fazlasına dahil tükürmek olabilir veya çoklu mesajlar birleştirilmiş olabilir) Kodu paylaşma veya yayınlama, sadece kamu tüketimini temizlemek için zamanım olmadı. İlgilinen biri varsa beni haberdar etsin.

+0

Kodunuzu paylaşabilir misiniz? –

+0

@ParagBafna Bir araya getirilmeden önce birkaç gün/hafta olabilir. Yapabileceğim en kısa sürede yapar. – s4y

+0

Merhaba. Senin kodunla ilgilenirim. Lütfen. – Arvin

0

Neden POSIX adlandırılmış yöneltme denemiyoruz? Ben UNIX alanı yuvalarını kullandı Sonunda

http://www.ecst.csuchico.edu/~beej/guide/ipc/fifos.html

+0

Cevabınız için teşekkürler! Adlandırılmış boruların iki ucu olduğunu anlayabildiğim kadarıyla - ve bu proje için tek sunuculu, çok müşterili bir ilişkiye ihtiyacım vardı. – s4y

+0

D e a d l i n k. –

6

alanı soketlerine ile soket işlemek için iyi bir öğretici üzerine kapmak için zor bir ceviz. Bunu yapmayan ve ilgilenen herkes için bunun peşinden git. Daha sonra bir başarı hissi ortaya çıkacaktır. Ancak, Beej ve bu site veya Apple'dan gelen bilgilerle bile çok fazla bağlantı kesildi. Burada, ARC'nin etkin olduğu Kakao için kesin bir örnek sunuyoruz. Sidnicious ve onun örneğini bekliyordum, ama hiçbir şey görmedim, bu yüzden kendimle baş etmeye karar verdim.

Burada sahip olduğum üç başlıklı bir başlık ve .m Uygulama dosyasıdır. Bir superclass arabirimi ve daha sonra devralan bir sunucu ve istemci arabirimi. Bazı sınırlı testler yaptım ve güzel çalışıyor gibi görünüyor. Ancak, her zaman yenilik arayan yani ... lütfen bana bildirin

Başlık Dosya:

typedef enum _CommSocketServerStatus { 

    CommSocketServerStatusUnknown  = 0, 
    CommSocketServerStatusRunning  = 1, 
    CommSocketServerStatusStopped  = 2, 
    CommSocketServerStatusStarting  = 3, 
    CommSocketServerStatusStopping  = 4 

} CommSocketServerStatus; 

typedef enum _CommSocketClientStatus { 

    CommSocketClientStatusUnknown  = 0, 
    CommSocketClientStatusLinked  = 1, 
    CommSocketClientStatusDisconnected = 2, 
    CommSocketClientStatusLinking  = 3, 
    CommSocketClientStatusDisconnecting = 4 

} CommSocketClientStatus; 

@class CommSocketServer, CommSocketClient; 

@protocol CommSocketServerDelegate <NSObject> 
@optional 
- (void) handleSocketServerStopped:(CommSocketServer *)server; 
- (void) handleSocketServerMsgURL:(NSURL *)aURL   fromClient:(CommSocketClient *)client; 
- (void) handleSocketServerMsgString:(NSString *)aString fromClient:(CommSocketClient *)client; 
- (void) handleSocketServerMsgNumber:(NSNumber *)aNumber fromClient:(CommSocketClient *)client; 
- (void) handleSocketServerMsgArray:(NSArray *)aArray fromClient:(CommSocketClient *)client; 
- (void) handleSocketServerMsgDict:(NSDictionary *)aDict fromClient:(CommSocketClient *)client; 
@end 

@protocol CommSocketClientDelegate <NSObject> 
@optional 
- (void) handleSocketClientDisconnect:(CommSocketClient *)client; 
- (void) handleSocketClientMsgURL:(NSURL *)aURL   client:(CommSocketClient *)client; 
- (void) handleSocketClientMsgString:(NSString *)aString client:(CommSocketClient *)client; 
- (void) handleSocketClientMsgNumber:(NSNumber *)aNumber client:(CommSocketClient *)client; 
- (void) handleSocketClientMsgArray:(NSArray *)aArray client:(CommSocketClient *)client; 
- (void) handleSocketClientMsgDict:(NSDictionary *)aDict client:(CommSocketClient *)client; 
@end 

@interface CommSocket : NSObject 
@property (readonly, nonatomic, getter=isSockRefValid) BOOL sockRefValid; 
@property (readonly, nonatomic, getter=isSockConnected) BOOL sockConnected; 
@property (readonly, nonatomic) CFSocketRef sockRef; 
@property (readonly, strong, nonatomic) NSURL *sockURL; 
@property (readonly, strong, nonatomic) NSData *sockAddress; 
@property (readonly, strong, nonatomic) NSString *sockLastError; 
@end 

@interface CommSocketServer : CommSocket <CommSocketClientDelegate> { id <CommSocketServerDelegate> delegate; } 
@property (readwrite, strong, nonatomic) id delegate; 
@property (readonly, strong, nonatomic) NSSet *sockClients; 
@property (readonly, nonatomic) CommSocketServerStatus sockStatus; 
@property (readonly, nonatomic) BOOL startServer; 
@property (readonly, nonatomic) BOOL stopServer; 
- (id) initWithSocketURL:(NSURL *)socketURL; 
+ (id) initAndStartServer:(NSURL *)socketURL; 
- (void) addConnectedClient:(CFSocketNativeHandle)handle; 

- (void) messageClientsURL:(NSURL *)aURL; 
- (void) messageClientsString:(NSString *)aString; 
- (void) messageClientsNumber:(NSNumber *)aNumber; 
- (void) messageClientsArray:(NSArray *)aArray; 
- (void) messageClientsDict:(NSDictionary *)aDict; 

@end 

@interface CommSocketClient : CommSocket { id <CommSocketClientDelegate> delegate; } 
@property (readwrite, strong, nonatomic) id delegate; 
@property (readonly, nonatomic) CommSocketClientStatus sockStatus; 
@property (readonly, nonatomic) CFRunLoopSourceRef sockRLSourceRef; 
@property (readonly, nonatomic) BOOL startClient; 
@property (readonly, nonatomic) BOOL stopClient; 
- (id) initWithSocketURL:(NSURL *)socketURL; 
- (id) initWithSocket:(CFSocketNativeHandle)handle; 
+ (id) initAndStartClient:(NSURL *)socketURL; 
+ (id) initWithSocket:(CFSocketNativeHandle)handle; 

- (void) messageReceived:(NSData *)data; 
- (BOOL) messageURL:(NSURL *)aURL; 
- (BOOL) messageString:(NSString *)aString; 
- (BOOL) messageNumber:(NSNumber *)aNumber; 
- (BOOL) messageArray:(NSArray *)aArray; 
- (BOOL) messageDict:(NSDictionary *)aDict; 

@end 

Uygulama Dosyası: (Ben üç bölüm halinde sunacak)

Bölüm I (Üst sınıf)

#import "CommSocket.h" 

#import <sys/un.h> 
#import <sys/socket.h> 

#pragma mark Socket Superclass: 

@interface CommSocket() 
@property (readwrite, nonatomic) CFSocketRef sockRef; 
@property (readwrite, strong, nonatomic) NSURL *sockURL; 
@end 

@implementation CommSocket 
@synthesize sockConnected; 
@synthesize sockRef, sockURL; 

- (BOOL) isSockRefValid { 
    if (self.sockRef == nil) return NO; 
    return (BOOL)CFSocketIsValid(self.sockRef); 
} 

- (NSData *) sockAddress { 

    struct sockaddr_un address; 
    address.sun_family = AF_UNIX; 
    strcpy(address.sun_path, [[self.sockURL path] fileSystemRepresentation]); 
    address.sun_len = SUN_LEN(&address); 
    return [NSData dataWithBytes:&address length:sizeof(struct sockaddr_un)]; 
} 

- (NSString *) sockLastError { 
    return [NSString stringWithFormat:@"%s (%d)", strerror(errno), errno ]; 
} 

@end 

Bölüm II (sunucu)

Not: sunucu reus Kendisine bağlanan istemciler için İstemci kodu. OO programlama, bunu sevmeliyim!

#pragma mark - Socket: Client 
#pragma mark - 

@interface CommSocketClient() 
@property (readonly, nonatomic) BOOL startClientCleanup; 
@property (readwrite, nonatomic) CommSocketClientStatus sockStatus; 
@property (readwrite, nonatomic) CFRunLoopSourceRef sockRLSourceRef; 
static void SocketClientCallback (CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, void *info); 
@end 

#pragma mark - Client Implementation: 

@implementation CommSocketClient 

static NSTimeInterval const kCommSocketClientTimeout = 5.0; 

@synthesize delegate; 
@synthesize sockStatus; 
@synthesize sockRLSourceRef; 

#pragma mark - Helper Methods: 

- (BOOL) socketClientCreate:(CFSocketNativeHandle)sock { 

    if (self.sockRef != nil) return NO; 
    CFSocketContext context = { 0, (__bridge void *)self, nil, nil, nil }; 
    CFSocketCallBackType types = kCFSocketDataCallBack; 
    CFSocketRef refSock = CFSocketCreateWithNative(nil, sock, types, SocketClientCallback, &context); 

    if (refSock == nil) return NO; 

    int opt = 1; 
    setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void *)&opt, sizeof(opt)); 

    self.sockRef = refSock; 
    CFRelease(refSock); 

    return YES; 
} 

- (BOOL) socketClientBind { 
    if (self.sockRef == nil) return NO; 
    if (CFSocketConnectToAddress(self.sockRef, 
            (__bridge CFDataRef)self.sockAddress, 
            (CFTimeInterval)kCommSocketClientTimeout) != kCFSocketSuccess) return NO; 
    return YES; 
} 

#pragma mark - Client Messaging: 

- (void) messageReceived:(NSData *)data { 

    id msg = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 

    if ([msg isKindOfClass:[NSURL class]]) { 

     if ([self.delegate respondsToSelector:@selector(handleSocketClientMsgURL:client:)]) 
      [self.delegate handleSocketClientMsgURL:(NSURL *)msg client:self]; 
    } 

    else if ([msg isKindOfClass:[NSString class]]) { 

     if ([self.delegate respondsToSelector:@selector(handleSocketClientMsgString:client:)]) 
      [self.delegate handleSocketClientMsgString:(NSString *)msg client:self]; 
    } 

    else if ([msg isKindOfClass:[NSNumber class]]) { 

     if ([self.delegate respondsToSelector:@selector(handleSocketClientMsgNumber:client:)]) 
      [self.delegate handleSocketClientMsgNumber:(NSNumber *)msg client:self]; 
    } 

    else if ([msg isKindOfClass:[NSArray class]]) { 

     if ([self.delegate respondsToSelector:@selector(handleSocketClientMsgArray:client:)]) 
      [self.delegate handleSocketClientMsgArray:(NSArray *)msg client:self]; 
    } 

    else if ([msg isKindOfClass:[NSDictionary class]]) { 

     if ([self.delegate respondsToSelector:@selector(handleSocketClientMsgDict:client:)]) 
      [self.delegate handleSocketClientMsgDict:(NSDictionary *)msg client:self]; 
    } 
} 

- (BOOL) messageData:(NSData *)data { 

    if (self.isSockConnected) { 

     if (kCFSocketSuccess == CFSocketSendData(self.sockRef, 
                nil, 
                (__bridge CFDataRef)data, 
                kCommSocketClientTimeout)) 
      return YES; 

    } return NO; 
} 

- (BOOL) messageURL:(NSURL *)aURL   { return [self messageData:[NSKeyedArchiver archivedDataWithRootObject:aURL]]; } 
- (BOOL) messageString:(NSString *)aString { return [self messageData:[NSKeyedArchiver archivedDataWithRootObject:aString]]; } 
- (BOOL) messageNumber:(NSNumber *)aNumber { return [self messageData:[NSKeyedArchiver archivedDataWithRootObject:aNumber]]; } 
- (BOOL) messageArray:(NSArray *)aArray { return [self messageData:[NSKeyedArchiver archivedDataWithRootObject:aArray]]; } 
- (BOOL) messageDict:(NSDictionary *)aDict { return [self messageData:[NSKeyedArchiver archivedDataWithRootObject:aDict]]; } 

#pragma mark - Start/Stop Client: 

- (BOOL) startClientCleanup { [self stopClient]; return NO; } 

- (BOOL) startClient { 

    if (self.sockStatus == CommSocketClientStatusLinked) return YES; 
    self.sockStatus = CommSocketClientStatusLinking; 

    CFSocketNativeHandle sock = socket(AF_UNIX, SOCK_STREAM, 0); 
    if (![self socketClientCreate:sock]) return self.startClientCleanup; 
    if (![self socketClientBind]  ) return self.startClientCleanup; 

    CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, self.sockRef, 0); 
    CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes); 

    self.sockRLSourceRef = sourceRef; 
    CFRelease(sourceRef); 

    self.sockStatus = CommSocketClientStatusLinked; 
    return YES; 
} 

- (BOOL) stopClient { 

    self.sockStatus = CommSocketClientStatusDisconnecting; 

    if (self.sockRef != nil) { 

     if (self.sockRLSourceRef != nil) { 

      CFRunLoopSourceInvalidate(self.sockRLSourceRef); 
      self.sockRLSourceRef = nil; 
     } 

     CFSocketInvalidate(self.sockRef); 
     self.sockRef = nil; 
    } 

    if ([self.delegate respondsToSelector:@selector(handleSocketClientDisconnect:)]) 
     [self.delegate handleSocketClientDisconnect:self]; 

    self.sockStatus = CommSocketClientStatusDisconnected; 

    return YES; 
} 

#pragma mark - Client Validation: 

- (BOOL) isSockConnected { 

    if (self.sockStatus == CommSocketClientStatusLinked) 
     return self.isSockRefValid; 

    return NO; 
} 

#pragma mark - Initialization: 

+ (id) initAndStartClient:(NSURL *)socketURL { 

    CommSocketClient *client = [[CommSocketClient alloc] initWithSocketURL:socketURL]; 
    [client startClient]; 
    return client; 
} 

+ (id) initWithSocket:(CFSocketNativeHandle)handle { 

    CommSocketClient *client = [[CommSocketClient alloc] initWithSocket:handle]; 
    return client; 
} 

- (id) initWithSocketURL:(NSURL *)socketURL { 

    if ((self = [super init])) { 

     self.sockURL = socketURL; 
     self.sockStatus = CommSocketClientStatusDisconnected; 

    } return self; 
} 

- (id) initWithSocket:(CFSocketNativeHandle)handle { 

    if ((self = [super init])) { 

     self.sockStatus = CommSocketClientStatusLinking; 

     if (![self socketClientCreate:handle]) [self startClientCleanup]; 

     else { 

      CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, self.sockRef, 0); 
      CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes); 

      self.sockRLSourceRef = sourceRef; 
      CFRelease(sourceRef); 

      self.sockStatus = CommSocketClientStatusLinked; 
     } 

    } return self; 
} 

- (void) dealloc { [self stopClient]; } 

#pragma mark - Client Callback: 

static void SocketClientCallback (CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { 

    CommSocketClient *client = (__bridge CommSocketClient *)info; 

    if (kCFSocketDataCallBack == type) { 

     NSData *objData = (__bridge NSData *)data; 

     if ([objData length] == 0) 
      [client stopClient]; 

     else 
      [client messageReceived:objData]; 
    } 
} 

@end 

Tamam

#pragma mark - Socket: Server 
#pragma mark - 

@interface CommSocketServer() 
@property (readonly, nonatomic) BOOL startServerCleanup; 
@property (readwrite, nonatomic) CommSocketServerStatus sockStatus; 
@property (readwrite, strong, nonatomic) NSSet *sockClients; 
static void SocketServerCallback (CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, void *info); 
@end 

#pragma mark - Server Implementation: 

@implementation CommSocketServer 

@synthesize delegate; 
@synthesize sockStatus; 
@synthesize sockClients; 

#pragma mark - Helper Methods: 

- (BOOL) socketServerCreate { 

    if (self.sockRef != nil) return NO; 
    CFSocketNativeHandle sock = socket(AF_UNIX, SOCK_STREAM, 0); 
    CFSocketContext context = { 0, (__bridge void *)self, nil, nil, nil }; 
    CFSocketRef refSock = CFSocketCreateWithNative(nil, sock, kCFSocketAcceptCallBack, SocketServerCallback, &context); 

    if (refSock == nil) return NO; 

    int opt = 1; 
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt)); 
    setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void *)&opt, sizeof(opt)); 

    self.sockRef = refSock; 
    CFRelease(refSock); 

    return YES; 
} 

- (BOOL) socketServerBind { 
    if (self.sockRef == nil) return NO; 
    unlink([[self.sockURL path] fileSystemRepresentation]); 
    if (CFSocketSetAddress(self.sockRef, (__bridge CFDataRef)self.sockAddress) != kCFSocketSuccess) return NO; 
    return YES; 
} 

#pragma mark - Connected Clients: 

- (void) disconnectClients { 


    for (CommSocketClient *client in self.sockClients) 
     [client stopClient]; 

    self.sockClients = [NSSet set]; 
} 

- (void) disconnectClient:(CommSocketClient *)client { 

    @synchronized(self) { 
     NSMutableSet *clients = [NSMutableSet setWithSet:self.sockClients]; 

     if ([clients containsObject:client]) { 

      if (client.isSockRefValid) [client stopClient]; 
      [clients removeObject:client]; 
      self.sockClients = clients; 
    } } 
} 

- (void) addConnectedClient:(CFSocketNativeHandle)handle { 

    @synchronized(self) { 
     CommSocketClient *client = [CommSocketClient initWithSocket:handle]; 
     client.delegate = self; 
     NSMutableSet *clients = [NSMutableSet setWithSet:self.sockClients]; 

     if (client.isSockConnected) { 
      [clients addObject:client]; 
      self.sockClients = clients; 
    } } 
} 

#pragma mark - Connected Client Protocols: 

- (void) handleSocketClientDisconnect:(CommSocketClient *)client { 

    [self disconnectClient:client]; 
} 

- (void) handleSocketClientMsgURL:(NSURL *)aURL client:(CommSocketClient *)client { 

    if ([self.delegate respondsToSelector:@selector(handleSocketServerMsgURL:server:fromClient:)]) 
     [self.delegate handleSocketServerMsgURL:aURL fromClient:client]; 
} 

- (void) handleSocketClientMsgString:(NSString *)aString client:(CommSocketClient *)client { 

    if ([self.delegate respondsToSelector:@selector(handleSocketServerMsgString:fromClient:)]) 
     [self.delegate handleSocketServerMsgString:aString fromClient:client]; 
} 

- (void) handleSocketClientMsgNumber:(NSNumber *)aNumber client:(CommSocketClient *)client { 

    if ([self.delegate respondsToSelector:@selector(handleSocketServerMsgNumber:fromClient:)]) 
     [self.delegate handleSocketClientMsgNumber:aNumber client:client]; 
} 

- (void) handleSocketClientMsgArray:(NSArray *)aArray client:(CommSocketClient *)client { 

    if ([self.delegate respondsToSelector:@selector(handleSocketServerMsgArray:fromClient:)]) 
     [self.delegate handleSocketServerMsgArray:aArray fromClient:client]; 
} 

- (void) handleSocketClientMsgDict:(NSDictionary *)aDict client:(CommSocketClient *)client { 

    if ([self.delegate respondsToSelector:@selector(handleSocketServerMsgDict:fromClient:)]) 
     [self.delegate handleSocketServerMsgDict:aDict fromClient:client]; 
} 

#pragma mark - Connected Client Messaging: 

- (void) messageClientsURL:(NSURL *)aURL { 
    for (CommSocketClient *client in self.sockClients) 
     [client messageURL:aURL]; 
} 

- (void) messageClientsString:(NSString *)aString { 
    for (CommSocketClient *client in self.sockClients) 
     [client messageString:aString]; 
} 

- (void) messageClientsNumber:(NSNumber *)aNumber { 
    for (CommSocketClient *client in self.sockClients) 
     [client messageNumber:aNumber]; 
} 

- (void) messageClientsArray:(NSArray *)aArray { 
    for (CommSocketClient *client in self.sockClients) 
     [client messageArray:aArray]; 
} 

- (void) messageClientsDict:(NSDictionary *)aDict { 
    for (CommSocketClient *client in self.sockClients) 
     [client messageDict:aDict]; 
} 

#pragma mark - Start/Stop Server: 

- (BOOL) startServerCleanup { [self stopServer]; return NO; } 

- (BOOL) startServer { 

    if (self.sockStatus == CommSocketServerStatusRunning) return YES; 
    self.sockStatus = CommSocketServerStatusStarting; 

    if (![self socketServerCreate]) return self.startServerCleanup; 
    if (![self socketServerBind] ) return self.startServerCleanup; 

    CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, self.sockRef, 0); 
    CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes); 
    CFRelease(sourceRef); 

    self.sockStatus = CommSocketServerStatusRunning; 
    return YES; 
} 

- (BOOL) stopServer { 

    self.sockStatus = CommSocketServerStatusStopping; 

    [self disconnectClients]; 

    if (self.sockRef != nil) { 

     CFSocketInvalidate(self.sockRef); 
     self.sockRef = nil; 
    } 

    unlink([[self.sockURL path] fileSystemRepresentation]); 

    if ([self.delegate respondsToSelector:@selector(handleSocketServerStopped:)]) 
     [self.delegate handleSocketServerStopped:self]; 

    self.sockStatus = CommSocketServerStatusStopped; 
    return YES; 
} 

#pragma mark - Server Validation: 

- (BOOL) isSockConnected { 

    if (self.sockStatus == CommSocketServerStatusRunning) 
     return self.isSockRefValid; 

    return NO; 
} 

#pragma mark - Initialization: 

+ (id) initAndStartServer:(NSURL *)socketURL { 

    CommSocketServer *server = [[CommSocketServer alloc] initWithSocketURL:socketURL]; 
    [server startServer]; 
    return server; 
} 

- (id) initWithSocketURL:(NSURL *)socketURL { 

    if ((self = [super init])) { 

     self.sockURL  = socketURL; 
     self.sockStatus = CommSocketServerStatusStopped; 
     self.sockClients = [NSSet set]; 

    } return self; 
} 

- (void) dealloc { [self stopServer]; } 

#pragma mark - Server Callback: 

static void SocketServerCallback (CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { 

    CommSocketServer *server = (__bridge CommSocketServer *)info; 

    if (kCFSocketAcceptCallBack == type) { 
     CFSocketNativeHandle handle = *(CFSocketNativeHandle *)data; 
     [server addConnectedClient:handle]; 
    } 
} 

@end 

Bölüm III (müşteri), o kadar ve farklı işlemler çalışması gerekir.

Bunu yalnızca soket dosyasının nereye yerleştirileceği bir sunucu oluşturmak için kullanın.

  • (id) initAndStartServer: (NSURL *) socketURL;

Aynı şekilde, bir istemci bağlantısı

oluşturmak için kullanabilir
  • (id) initAndStartClient: (NSURL *) socketURL;

Geri kalan delege yöntemlerini içermelidir. Son olarak, url yolunu küçük tutun (bunun için gerçek bir denetim eklemeyin) ve bunları ayrı bir NSOperationQueue'da (test edilmemiş olsa da) oluşturabilirsiniz.

Bu, çalışan bir örnek olarak dışarıda bir kişi yardımcı olur umarım. Arvin

+0

Awesome !!! Bu temiz kod için çok teşekkür ederim. Resmi belgelerinde eksik olan tam olarak budur. – codingFriend1

+0

Yolun 103 karakterden uzun olması durumunda '-sockAddress' yönteminin strcpy()' strcpy() 'nin yapısının sonuna gelmesi gibi görünüyor. Bunu düzeltmenin yolunun büyük bir NSMutableData oluşturmak, yolu kopyalamak ve daha sonra verileri "SUN_LEN (& address)" olarak yeniden boyutlandırmak olduğunu tahmin ediyorum. Bu durumda 'sun_len' alanının ne olması gerektiği bana açık değil; imzasız bir karakterin büyüklüğüyle sınırlıdır. –

İlgili konular