2009-06-12 13 views
5

मैं यूनिक्स डोमेन सॉकेट का उपयोग करके कोको एप्लिकेशन में आईपीसी लागू करना चाहता हूं, जिसके साथ मुझे कोई अनुभव नहीं है। मैंने ऐप्पल की CFLocalServer उदाहरण प्रोजेक्ट पाया, लेकिन यह सी में लिखा गया है और अच्छी तरह से, काफी जटिल (और हाँ, मैंने इसे सबसे अधिक पढ़ा है)।यूनिक्स डोमेन सॉकेट और कोको

क्या सीएफएलोकलसेवर में अभी भी अत्याधुनिक तकनीकें प्रदर्शित की गई हैं, या क्या कोको/फाउंडेशन के साथ उद्देश्य-सी में यूनिक्स डोमेन सॉकेट को लागू करने का कोई तरीका है?

मैं NSSocketPort और NSFileHandle रों (जो अमूर्त की एक स्वस्थ राशि है, जो इस परियोजना के लिए बहुत अच्छा है प्रदान करते हैं) और Mike Bean's Networking in Cocoa में कुछ बहुत से संबंधित कोड मिलीं लेकिन वे यह सभी बनाने के लिए सक्षम किया गया है के साथ खेल रहा हूँ अभी तक काम करो

कोई भी इससे पहले किया?

उत्तर

4

अंत में, मैं यूनिक्स डोमेन सॉकेट का उपयोग किया था, और वे बहुत अच्छी तरह से काम करते हैं: मैक OSX एक POSIX ish ऑपरेटिंग BSD पर आधारित है, तो यह सीधे आगे होना चाहिए प्रणाली है। मैंने लॉन्च किया है मेरे सर्वर के लिए सॉकेट सेट किया है (लेकिन इसे स्वयं लिखने के लिए सफलतापूर्वक कोड लिखा है), और क्लाइंट से कनेक्ट है।

बातें मुझे पता चला:

  • आप NSFileHandle

  • में कनेक्शन के दोनों सिरों आप सॉकेट करने के लिए एक कनेक्शन बनाने के लिए ग्राहक के पक्ष connect() उपयोग करने की आवश्यकता है लपेट कर सकते हैं

  • आपको क्लाइंट और सर्वर दोनों को SIGPIPE

  • को अनदेखा करना चाहिए यदि आपको शून्य-लंबाई वाले डेटा के साथ वापस बुलाया जाता है, इसका मतलब है कि सॉकेट के दूसरे छोर पर चीज डिस्कनेक्ट हो गई है (यानी। सर्वर/क्लाइंट बाहर निकला)। इसे फिर से से डेटा पढ़ने की कोशिश मत करो, या बस एक और शून्य लंबाई पढ़ कॉलबैक मिलता है (हमेशा के लिए और कभी)

  • आप स्वयं उत्तरदायी होंगे - बंद करने के लिए और इस मामले में सॉकेट के अपने अंत रिलीज सुनिश्चित करें सॉकेट भर में परिसीमन और कोडांतरण भेजे जाने वाले संदेशों के लिए (एक छोर पर भेजा किसी एक संदेश दूसरे छोर पर एक से अधिक में थूक हो सकता है, या एक से अधिक संदेशों विलय हो सकता है)

मैं करने में खुशी होगी कोड साझा या प्रकाशित करें, बस सार्वजनिक खपत के लिए इसे साफ करने का समय नहीं है। अगर किसी को दिलचस्पी है तो मुझे बताएं।

+0

क्या आप अपना कोड साझा कर सकते हैं? –

+0

@ParagBafna इसे एक साथ रखने से पहले कुछ दिन/सप्ताह हो सकते हैं। जितनी जल्दी हो सके इसे करूँगा। – s4y

+0

हाय। मुझे आपके कोड में दिलचस्पी होगी। कृप्या। – Arvin

0

क्यों पॉज़िक्स नामित पाइप का प्रयास न करें।

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

+0

उत्तर के लिए धन्यवाद! जहां तक ​​मैं नामित पाइपों को बता सकता हूं कि दो सिरों हैं - और इस परियोजना के लिए, मुझे एक-सर्वर, कई-ग्राहक संबंधों की आवश्यकता थी। – s4y

+0

डी ई डी डी आई एन के। –

6

यूनिक्स डोमेन सॉकेट के साथ अपने सॉकेट से निपटने के लिए एक अच्छा ट्यूटोरियल है पर हड़पने के लिए एक कठिन अखरोट है। किसी भी व्यक्ति के लिए ऐसा नहीं किया है, और रुचि है तो इसके लिए जाओ। उपलब्धि की भावना बाद में आ जाएगी। हालांकि, यहां तक ​​कि बीज और इस साइट या ऐप्पल से भी जानकारी के साथ कई डिस्कनेक्ट हैं। मैं यहां कोको के लिए एक निर्णायक नमूना पेश कर रहा हूं जिसमें एआरसी सक्षम है। मैं सिडनीश और उसके नमूने की प्रतीक्षा कर रहा था, लेकिन कभी भी कुछ नहीं देखा, इसलिए मैंने अभी खुद से निपटने का फैसला किया।

मेरे पास जो कुछ है वह हैडर और .एम कार्यान्वयन फ़ाइल तीन इंटरफेस के साथ है। एक सुपरक्लास इंटरफ़ेस और उसके बाद एक सर्वर और क्लाइंट इंटरफ़ेस जो वारिस करता है। मैंने कुछ सीमित परीक्षण किया और ऐसा लगता है कि यह अच्छी तरह से काम करता है। हालांकि, हमेशा सुधार की तलाश में तो कृपया मुझे बताएं ...

हैडर फ़ाइल:

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 

कार्यान्वयन फ़ाइल: (मैं तीन वर्गों में पेश करेंगे)

खंड I (सुपर क्लास)

#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 

खंड II (सर्वर)

नोट: सर्वर Reus क्लाइंट कोड उन ग्राहकों के लिए है जो स्वयं से जुड़ते हैं। ओओ-प्रोग्रामिंग, इसे प्यार करना होगा!

#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 

धारा III (क्लाइंट)

#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 

ठीक है, कि यह है और यह विभिन्न प्रक्रियाओं से काम करना चाहिए।

बस सॉकेट फ़ाइल को कहां रखा जाए, इसके पथ के साथ सर्वर बनाने के लिए इसका उपयोग करें।

  • (आईडी) initAndStartServer: (NSURL *) socketURL;

इसी तरह, एक ग्राहक संबंध

बनाने के लिए इस का उपयोग
  • (आईडी) initAndStartClient: (NSURL *) socketURL;

शेष शामिल प्रतिनिधि विधियों के साथ सरल होना चाहिए। अंत में, यूआरएल पथ को छोटा रखें (इसके लिए कोई वास्तविक जांच नहीं जोड़ें) और आप इन्हें एक अलग NSOperationQueue (हालांकि अनचाहे) में तुरंत चालू कर सकते हैं।

आशा है कि यह किसी को पूर्ण कार्य नमूना के रूप में वहां मदद करेगा। अरविन

+0

बहुत बढ़िया !!! इस स्वच्छ कोड के लिए बहुत बहुत धन्यवाद। यह वही है जो आधिकारिक दस्तावेज़ों में गायब है। – codingFriend1

+0

ऐसा लगता है कि पथ '103' से अधिक लंबा है, तो यह आपकी '-sockAddress' विधि' स्ट्रक्पी() 'स्ट्रक्पी()' के अंतराल से परे होगा। मैं अनुमान लगा रहा हूं कि इसे ठीक करने का तरीका एक बड़ा एनएसएमयूटेबलडेटा बनाना है, पथ कॉपी करें और फिर डेटा को 'SUN_LEN (& पता)' में आकार दें। यह मुझे स्पष्ट नहीं है कि उस मामले में 'sun_len' फ़ील्ड क्या होना चाहिए; यह एक 'हस्ताक्षरित चार' के आकार से सीमित है। –

संबंधित मुद्दे