美文网首页Android
Binder理论基础(一)------通信结构与通信模型

Binder理论基础(一)------通信结构与通信模型

作者: 小昕是魔王 | 来源:发表于2019-08-18 16:42 被阅读0次

    引言

    ​ Android的IPC采用的C/S架构,这样的话各个进程可以去实现自己的功能,若需要使用自己未实现但其他进程实现了的功能,则可以很方便的作为调用客户端去访问实现该功能的服务端从而使用其对应功能。例如,要使用视频,音频等功能只需作为客户端去访问实现视频,音频功能接口的进程服务端,然后调用服务端的对应接口方法即可。

    为什么是Binder

    ​ 由于Android是基于Linux系统开发的操作系统,所以Linux的固有的IPC方式,在Android上也是适用的,但要达到上述的C/S架构模式,只有Socket套接字才行,但是Socket的传输性能较差,通常用于低频的IPC通信,所以在Android上实现了一套Binder机制用于在Android上进行IPC通信。

    ​ 那么Binder为何被选中作为Android的IPC机制呢?上述说到,Linux原本支持的IPC中只有Socket采用的是C/S架构,但性能不好,这当然是原因之一。说到性能的话,我们从传输性能,安全性能方面说起。

    传输性能

    ​ 由于Linux对于进程有着沙盒机制,即每个进程被“沙盒”封装起来,进程间彼此独立,这样当一个进程崩溃的话,其他进程仍可以正常运行,系统仍能正常运行。但有时需要进程间传递数据,进行通信,那么就提供了一系列的IPC方式,如:管道,共享内存,消息队列,信号量和Socket。

    ​ 但由于进程间通信都需要经过Linux内核,在内核中直接进行通信,所以就涉及到进程将数据拷贝到Linux内核的操作。除共享内存外,其余方式都至少需要拷贝2次(进程用户空间拷贝至内核空间,再从内核空间拷贝至目标进程的用户空间,共享内存无需拷贝)。详情可见下表:

    IPC方式 拷贝次数
    共享内存 0
    Binder 1
    管道/消息队列/信号量/Socket 2

    为什么Binder只需一次呢?因为Binder在Linux内核空间独立出了一块区域,可直接读取服务端数据,只需要客户端将数据拷贝至此处即可。

    ​ 由上可看到,传输次数减少了,带来的资源消耗就少了,从而加大了传输性能。

    简述之:Binder相对而言减少了数据拷贝次数达到提高传输性能的目的。

    安全性能

    ​ 那么,为什么Binder更具安全性呢?纵观其他的IPC方式,我们无法得知进行通信的端口是否合法(满足要求),即无论是谁,只要搭上了这条链路,即可进行数据交换。然而,Binder对每个进程都分配了UID/PID,当通过Binder进行IPC时,系统会去核对UID/PID是否合法,只要系统认为合法的PID,才能搭上Binder的车。如此,在IPC上增加一道关卡,保障IPC通信安全,所以相对其他IPC方式更具安全性。

    简述之:Binder通过UID/PID来保证通信双方的合法性,进而达到IPC间消息传输的安全性。

    Binder通信模型

    ​ 说到通信模型,主要是通信的组成成员和其架构模式。架构上文已说到,采用的C/S架构,那么这里主要说说组成成员。

    ​ Binder的组成成员共有四员大将:ServerClientServiceManagerBinder驱动。

    Binder驱动

    ​ Binder驱动,虽然叫驱动,但并不是真正的硬件驱动,而只是实现了驱动效果的一套代码而已。并且它运行在内核区,因此它是真正达到IPC效果的地方。

    ​ 上述说到,它实现了驱动效果,即实现驱动的一些方法如epoll()什么的。使用起来和真正的操作驱动并未差别。

    Server和Server中的Binder

    ​ Server作为Binder架构中服务端,是提供功能的一端,通过Binder暴露功能调用接口给外部,任何进程拿到其Binder,即可通过Binder调用功能接口去调用功能。在Server中,Binder是以实体存在。外部或得的是Binder实体的引用,可以说指针或句柄,都是一个意思,因为是Android开发者,说引用的话比较好理解。

    Client和Client中的Binder

    ​ Client作为Binder架构中的客户端,是调用功能的一端,其拿到的Binder并非是Binder实体,而是指向该Binder实体的引用。

    ServiceManager和ServiceManager中的Binder

    ​ ServiceManager是类似于DNS的存在,存储了Binder名称和Binder实体的对应关系表。类似于域名和IP的对应关系。当有新的Service时,需要向ServiceManager进行注册,以便其他客户端想调用其功能时可以找到该Binder实体的引用。那么这必然是一次IPC过程,那么在还未搭建IPC桥梁的时候进行IPC必然是自相矛盾的,所以系统将ServiceManager的Binder实体的Binder引用干脆暴露出来,让所有进程都知道其Binder引用是什么,这样就可以直接进行注册。当新的Service向ServiceManager注册后,客户端调用时会在请求体中包含请求的Binder名称,ServiceManager会根据名称找到对应Binder的引用,然后告诉客户端,这样客户端就拿到服务端的Binder引用,然后就可以根据该引用去调用服务端的相关接口方法。

    特别鸣谢

    https://blog.csdn.net/universus/article/details/6211589 -------- Android Bander设计与实现 - 设计篇

    相关文章

      网友评论

        本文标题:Binder理论基础(一)------通信结构与通信模型

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