引言
我的文章比较多是对自己知识的梳理,有些概念没讲得那么清楚,但会贴出参考的链接,请大家自便
Binder 概述
基础概念
IPC : Inter-Process Communication (进程间的通信)
RPC : Remote Procedure Call (远程过程调用)
RPC是IPC的基础上进行了封装
简单例子: 大致有个概念
再简单的分析下要素 (led是例子)
1 | A(①封装数据 ②发送给B) ===>(IPC) B(①取出数据 @调用数据) |
Binder究竟是什么#
Binder是Android系统中负责每个用户进程与内核通信的驱动模块。
Binder的优势
推荐文章
主要是基于性能、稳定性和安全性几方面的原因。
性能
IPC | 数据拷贝次数 | MORE |
---|---|---|
共享内存 | 0 | |
Binder | 1 | |
Socket | 2 | |
管道 | 2 | |
消息队列 | 2 |
稳定性
Binder 基于 C/S 架构,架构清晰、职责明确又相互独立
安全性
传统的 IPC 没有任何安全措施,完全依赖上层协议来确保。
首先传统的 IPC 接收方无法获得对方可靠的进程用户ID/进程ID(UID/PID),从而无法鉴别对方身份。
Android 为每个安装好的 APP 分配了自己的 UID,故而进程的 UID 是鉴别进程身份的重要标志。
传统的 IPC 只能由用户在数据包中填入 UID/PID,但这样不可靠,容易被恶意程序利用。
可靠的身份标识只有由 IPC 机制在内核中添加。其次传统的 IPC 访问接入点是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接。同时 Binder 既支持实名 Binder,又支持匿名 Binder,安全性高。
IPC
以下对比 Binder IPC 对比 传统IPC 的区别
Linux 下的传统 IPC 通信原理
这种传统的 IPC 通信方式有两个问题:
性能低下,一次数据传递需要经历:内存缓存区 –> 内核缓存区 –> 内存缓存区,需要 2 次数据拷贝;
接收数据的缓存区由数据接收进程提供,但是接收进程并不知道需要多大的空间来存放将要传递过来的数据,因此只能开辟尽可能大的内存空间或者先调用 API 接收消息头来获取消息体的大小,这两种做法不是浪费空间就是浪费时间。
专栏:Android十万个为什么
什么是实名Binder?
什么是匿名Binder?
“内核缓存区” 和 “数据接收缓存区” 存在的意义
Linux是使用的虚拟内存寻址方式,虚拟内存需要映射一块真的的物理内存,
内核缓存区和数据接收区的映射就是指向了同一块物理内存。接收方下次也可能是发送方,如果共用一块缓存那么岂不是发送方,内核,接收方都指向了同一块物理内存,违反了进程隔离的设计原则。