美文网首页网络socket
NSConnection进程间通信ios版

NSConnection进程间通信ios版

作者: xiaoliang1 | 来源:发表于2018-11-20 12:32 被阅读98次

    之前逆向Mac上app时,发现有些app会用一个守护进程来和后开启的app来通信,虽然知道是进程间的通信,但是还是不太清楚这是一个怎么样的过程,怎么实现的。今天简单看了一下Mac上的进程间通信是怎么回事。
    我看的Mac上用NSConnection来实现进程间通信的。
    首先创建NSConnection并设置一个能提供一些协议方法的对象(setRootObject:),有些和http,ftp协议一样的方法。完了之后就注册名字,有点像注册服务一样。然后一个服务端就启动了。
    那个么客户端呢?
    直接用NSConnection的类方法rootProxyForConnectionWithRegisteredName获取一个NSDistantObject对象。然后设置他要代理的协议(setProtocolForProxy)。那么这个这个对象可以随意调用这些协议。
    就这样只要服务端的RootObject实现的协议,客户端都可以去调用。整个过程就像httpFTP等等一些协议一样。
    在iOS端呢,虽然你也可以用NSConnection来创建对象。但是却找不到头文件,点进去你会发现它只会在Foundation/NSPort中声名 是一个类

    WX20181120-121609@2x.png
    根本用不知道有什么方法来调用,最后我用私有方法获取整个类的声名,写并写进来一个文件,当然包含私有方法:
    @interface NSConnection : NSObject
    
    @property (readonly, copy) NSDictionary* statistics;
    @property double requestTimeout;
    @property double replyTimeout;
    @property (retain) id rootObject;
    //@property <NSConnectionDelegate>* delegate;
    @property BOOL independentConversationQueueing;
    @property (readonly, getter=isValid) BOOL valid;
    //@property (readonly, retain) id* rootProxy;
    @property (readonly, copy) NSArray* requestModes;
    @property (readonly, retain) NSPort* sendPort;
    @property (readonly, retain) NSPort* receivePort;
    @property (readonly) BOOL multipleThreadsEnabled;
    @property (readonly, copy) NSArray* remoteObjects;
    @property (readonly, copy) NSArray* localObjects;
    
    + (id) lookUpConnectionWithReceivePort:(id)arg1 sendPort:(id)arg2;
    + (id) connectionWithReceivePort:(id)arg1 sendPort:(id)arg2;
    + (id) connectionWithRegisteredName:(id)arg1 host:(id)arg2 usingNameServer:(id)arg3;
    + (id) serviceConnectionWithName:(id)arg1 rootObject:(id)arg2 usingNameServer:(id)arg3;
    + (id) allConnections;
    + (void) _enableLogging:(BOOL)arg1;
    + (id) connectionWithRegisteredName:(id)arg1 host:(id)arg2;
    + (id) rootProxyForConnectionWithRegisteredName:(id)arg1 host:(id)arg2;
    + (id) rootProxyForConnectionWithRegisteredName:(id)arg1 host:(id)arg2 usingNameServer:(id)arg3;
    + (id) serviceConnectionWithName:(id)arg1 rootObject:(id)arg2;
    + (id) currentConversation;
    + (void) _toggleLogging;
    + (void) initialize;
    + (id) defaultConnection;
    + (id) statistics;
    
    - (void) setRootObject:(id)arg1;
    - (id) rootObject;
    - (id) receivePort;
    - (id) sendPort;
    - (void) dispatchWithComponents:(id)arg1;
    - (void) handlePortMessage:(id)arg1;
    - (void) _portInvalidated:(id)arg1;
    - (void) removeRunLoop:(id)arg1;
    - (void) returnResult:(id)arg1 exception:(id)arg2 sequence:(unsigned int)arg3 imports:(id)arg4;
    - (id) initWithReceivePort:(id)arg1 sendPort:(id)arg2;
    - (id) rootProxy;
    - (BOOL) registerName:(id)arg1 withNameServer:(id)arg2;
    - (void) addRunLoop:(id)arg1;
    - (double) replyTimeout;
    - (double) requestTimeout;
    - (void) _setWhitelist:(id)arg1;
    - (void) sendReleasedProxies;
    - (id) keyedRootObject;
    - (void) addPortsToRunLoop:(id)arg1;
    - (void) removePortsFromRunLoop:(id)arg1;
    - (void) _encodeProxyList:(id)arg1 forCoder:(id)arg2;
    - (void) handleKeyedReleasedProxies:(id)arg1;
    - (void) handleUnkeyedReleasedProxies:(char*)arg1 length:(unsigned long)arg2;
    - (Class) _portCoderClass;
    - (void) _sendBeforeTime:(double)arg1 coder:(id)arg2 doAuthenticationCheck:(BOOL)arg3;
    - (BOOL) _verifyComponents:(id)arg1;
    - (id) portCoderWithComponents:(id)arg1;
    - (void) handlePortCoder:(id)arg1;
    - (void) handleRequest:(id)arg1 sequence:(unsigned int)arg2;
    - (void) decodeReleasedProxies:(id)arg1;
    - (id) newConversation;
    - (BOOL) _shouldDispatch:(id*)arg1 invocation:(id)arg2 sequence:(unsigned int)arg3 coder:(id)arg4;
    - (id) dispatchInvocation:(id)arg1;
    - (void) encodeReleasedProxies:(id)arg1;
    - (BOOL) hasRunLoop:(id)arg1;
    - (void) sendInvocation:(id)arg1 internal:(BOOL)arg2;
    - (void) _authenticateComponents:(id)arg1;
    - (BOOL) registerName:(id)arg1;
    - (void) setRequestTimeout:(double)arg1;
    - (void) setReplyTimeout:(double)arg1;
    - (BOOL) independentConversationQueueing;
    - (void) setIndependentConversationQueueing:(BOOL)arg1;
    - (void) addRequestMode:(id)arg1;
    - (void) removeRequestMode:(id)arg1;
    - (id) requestModes;
    - (id) replyMode;
    - (void) setReplyMode:(id)arg1;
    - (void) _incrementLocalProxyCount;
    - (void) _decrementLocalProxyCount;
    - (void) addClassNamed:(char*)arg1 version:(unsigned long)arg2;
    - (unsigned long) versionForClassNamed:(id)arg1;
    - (void) releaseWireID:(unsigned int)arg1 count:(unsigned long)arg2;
    - (id) remoteObjects;
    - (id) localObjects;
    - (Class) _portCoderClassWithComponents:(id)arg1;
    - (BOOL) sendWireCountForWireID:(unsigned int)arg1 port:(id)arg2;
    - (void) sendInvocation:(id)arg1;
    - (void) _setUseKC:(BOOL)arg1;
    - (void) enableMultipleThreads;
    - (BOOL) multipleThreadsEnabled;
    - (void) runInNewThread;
    - (id) retain;
    - (oneway void) release;
    - (void) dealloc;
    - (id) description;
    - (void) invalidate;
    - (void) setDelegate:(id)arg1;
    - (BOOL) isValid;
    - (id) delegate;
    - (id) init;
    - (void) run;
    - (id) statistics;
    
    @end
    

    接着你就能像Mac fountion下一样来写进程间的通信了。具体demo会在本文结束时提供地址,包含客户端和服务端。
    但是iOS所有App在进入后台时进程会被挂起,这时你可以用一些voip或者下载防止进程被挂起。一旦进程被挂起,客户端就拿不到任何数据了。。
    可运行测试的demo:https://github.com/LoveSVN/NSConnectionForios

    相关文章

      网友评论

        本文标题:NSConnection进程间通信ios版

        本文链接:https://www.haomeiwen.com/subject/tnmtqqtx.html