Binder通信机制介绍
1.Binder通信机制介绍
这篇文章会先对比Binder机制与Linux的通信机制的差别,了解为什么Android会另起炉灶,采用Binder。接着,会根据 Binder的机制,去理解什么是Service Manager,在C/S模型中扮演什么角色。最后,会从一次完整的通信活动中,去理解Binder通信的过程。
1.1 Android与Linux通信机制的比较
虽然Android继承使用Linux的内核,但Linux与Android的通信机制不同。
在Linux中使用的IPC通信机制如下:
传统IPC:无名pipe, signal, trace, 有名管道
AT&T Unix 系统V:共享内存,信号灯,消息队列
- BSD Unix:Socket
而在Android中,并没有使用这些,取而代之的是Binder机制。Binder机制是采用OpenBinder演化而来,在Android中使用它的原因如下:
采用C/S的通信模式。而在linux通信机制中,目前只有socket支持C/S的通信模式,但socket有其劣势,具体参看第二条。
- 有更好的传输性能。对比于Linux的通信机制,
socket:是一个通用接口,导致其传输效率低,开销大;
管道和消息队列:因为采用存储转发方式,所以至少需要拷贝2次数据,效率低;
共享内存:虽然在传输时没有拷贝数据,但其控制机制复杂(比如跨进程通信时,需获取对方进程的pid,得多种机制协同操作)。
- 安全性更高。Linux的IPC机制在本身的实现中,并没有安全措施,得依赖上层协议来进行安全控制。而Binder机制的 UID/PID是由Binder机制本身在内核空间添加身份标识,安全性高;并且Binder可以建立私有通道,这是linux的通信机制所无法实现的 (Linux访问的接入点是开放的)。
综上所述,Android采用Binder机制是有道理的。既然Binder机制这么多优点,那么我们接下来看看它是怎样通过C/S模型来实现的。
1.2Binder在Service服务中的作用
在android中,有很多Service都是通过binder来通信的,比如MediaServer旗下包含了众多service:
AudioFlinger 音频核心服务
AudioPolicyService:音频策略相关的重要服务
MediaPlayerService:多媒体系统中的重要服务
- CameraService:有关摄像/照相的重要服务
Binder在C/S中的流程如下:
Server注册服务。Server作为众多Service的拥有者,当它想向Client提供服务时,得先去Service Manager(以后缩写成SM)那儿注册自己的服务。Server可以向SM注册一个或多个服务。
Client申请服务。Client作为Service的使用者,当它想使用服务时,得向SM申请自己所需要的服务。Client可以申请一个或多个服务。
- 当Client申请服务成功后,Client就可以使用服务了。
SM一方面管理Server所提供的服务,同时又响应Client的请求并为之分配相应的服务。扮演的角色相当于月老,两边牵线。这种通信方式的好处是: 一方面,service和Client请求便于管理,另一方面在应用程序开发时,只需为Client建立到Server的连接,就可花很少时间和精力去实 现Server相应功能。那么,Binder与这个通信模式有什么关系呢?!其实,3者的通信方式就是Binder机制(例如:Server向SM注册服 务,使用Binder通信;Client申请请求,用的是Binder通讯)
1.3Binder通信机制流程(整体框架)
上图即是Binder的通信模型。我们可以发现:
Client和Server是存在于用户空间
Client与Server通信的实现,是由Binder驱动在内核空间实现
- SM作为守护进程,处理客户端请求,管理所有服务项。
为了方便理解,我们可以把SM理解成DNS服务器; 那么Binder Driver 就相当于路由的功能。这里就涉及到Client和Server是如何通信的问题。下面对1.2中提到的3个流程进行说明。
1.3.1 Server向SM注册服务
首先,XXXServer(XXX代表某个)在自己的进程中向Binder驱动申请创建一个XXXService的Binder的实体,
Binder驱动为这个XXXService创建位于内核中的Binder实体节点以及Binder的引用,注意,是将名字和新建的引用打包传递给SM(实体没有传给SM),通知SM注册一个名叫XXX的Service。
SM收到数据包后,从中取出XXXService名字和引用,填入一张查找表中。
- 此时,如果有Client向SM发送申请服务XXXService的请求,那么SM就可以在查找表中找到该Service的Binder引用,并把Binder引用(XXXBpBinder)返回给Client。
在进一步了解Binder通信机制之前,我们先弄清几个概念。
引用和实体。这里,对于一个用于通信的实体(可以理解成具有真实空间的Object),可以有多个该实体的引用(没有真实空间,可以理解成实体的 一个链接,操作引用就会操作对应链接上的实体)。如果一个进程持有某个实体,其他进程也想操作该实体,最高效的做法是去获得该实体的引用,再去操作这个引 用。
- 有些资料把实体称为本地对象,引用成为远程对象。可以这么理解:引用是从本地进程发送给其他进程来操作实体之用,所以有本地和远程对象之名。
1.3.2 一个问题-如何获得SM的远程接口
如果你足够细心,会发现这里有一个问题:
Sm和Server都是进程,Server向SM注册Binder需要进程间通信,当前实现的是进程间通信却又用到进程间通信。这就好比鸡生蛋、蛋生鸡,但至少得先有其中之一。
巧妙的Binder解决思路:
针对Binder的通信机制,Server端拥有的是Binder的实体;Client端拥有的是Binder的引用。
如果把SM看作Server端,让它在Binder驱动一运行起来时就有自己的Binder实体(代码中设置ServiceManager的Binder 其handle值恒为0)。这个Binder实体没有名字也不需要注册,所有的client都认为handle值为0的binder引用是用来与SM通信 的(代码中是这么实现的),那么这个问题就解决了。那么,Client和Server中这么达成协议了(handle值为0的引用是专门与SM通信之用 的),还不行,还需要让SM有handle值为0的实体才算大功告成。怎么实现的呢?!当一个进程调用Binder驱动时,使用 BINDER_SET_CONTEXT_MGR命令(在驱动的binder_ioctl中)将自己注册成SM时,Binder驱动会自动为它创建 Binder实体。这个Binder的引用对所有的Client都为0。
1.3.3 Client从SM获得Service的远程接口
Server向SM注册了Binder实体及其名字后,Client就可以通过Service的名字在SM的查找表中获得该Binder的引用了 (BpBinder)。Client也利用保留的handle值为0的引用向SM请求访问某个Service:我申请访问XXXService的引用。 SM就会从请求数据包中获得XXXService的名字,在查找表中找到该名字对应的条目,取出Binder的引用打包回复给client。之 后,Client就可以利用XXXService的引用使用XXXService的服务了。
如果有更多的Client请求该Service,系统中就会有更多的Client获得这个引用。
1.3.4建立C/S通路后
首先要理清一个概念:client拥有自己Binder的实体,以及Server的Binder的引用;Server拥有自己Binder的实体,以及Client的Binder的引用。我们也可以从接收方和发送方的方式来理解:
从client向Server发数据:Client为发送方,拥有Binder的实体;Server为接收方,拥有Binder的引用
- 从server向client发数据:Server为发送方,拥有Binder的实体;client为接收方,拥有Binder的引用。
也就是说,我们在建立了C/S通路后,无需考虑谁是Client谁是Server,只要理清谁是发送方谁是接收方,就能知道Binder的实体和引用在哪边。
建立CS通路后的流程:(当接收方获得Binder的实体,发送方获得Binder的引用后)
发送方会通过Binder实体请求发送操作。
Binder驱动会处理这个操作请求,把发送方的数据放入写缓存(binder_write_read.write_buffer) (对于接收方为读缓冲区),并把read_size(接收方读数据)置为数据大小(对于具体的实现后面会介绍);
接收方之前一直在阻塞状态中,当写缓存中有数据,则会读取数据,执行命令操作
- 接收方执行完后,会把返回结果同样用binder_transaction_data结构体封装,写入写缓冲区(对于发送方,为读缓冲区)
1.3.5 匿名Binder
之前在介绍Android使用Binder机制的优点中,提到Binder可以建立点对点的私有通道,匿名Binder就是这种方式。在 Binder通信中,并不是所有用来通信的Binder实体都需要注册给SM广而告之的,Server可以通过已建立的实体Binder连接将创建的 Binder实体传给Client。而这个Binder没有向SM注册名字。这样Server与Client的通信就有很高的隐私性和安全性。
这样,整个Binder的通信流程就介绍完毕了,但是对于具体的代码实现(比如binder_transaction_data是什 么?binder_write_read.write_buffer又是什么?具体的驱动和逻辑实现又是怎么样?),在后面章节中会一一介绍。
几点疑问:
1. 是谁,怎么样成为SM守护进程,handle为0的binder实体什么时候创建?
2. binder引用和实体是如何创建的?在驱动中如何实现的通信?
3. 在SM中,binder实体是怎样转换成为引用的?
4. Server是如何注册服务,Client是如何获取服务的?
Binder通信机制介绍的更多相关文章
- 从AIDL开始谈Android进程间Binder通信机制
转自: http://tech.cnnetsec.com/585.html 本文首先概述了Android的进程间通信的Binder机制,然后结合一个AIDL的例子,对Binder机制进行了解析. 概述 ...
- 笔记:Binder通信机制
TODO: 待修正 Binder简介 Binder是android系统中实现的一种高效的IPC机制,平常接触到的各种XxxManager,以及绑定Service时都在使用它进行跨进程操作. 它的实现基 ...
- android的Binder通信机制java层浅谈-android学习之旅(88)
1.Service Manager的Java代理对象 在Java层中,Service Manager的代理对象类型为ServiceManagerProxy.它继承并且实现了IServiceManage ...
- android binder 进程间通信机制6-Binder进程间通信机制的JAVA接口
Binder间进程通信的JAVA层接口,主要是通过JNI方法来调用Binder库的C/C++接口 在JAVA层,将Service组件称为JAVA服务,Service组件的代理称为JAVA服务代理. 一 ...
- 1、netlink 连接器 通信机制
使用netlink之前,先参考一下资料:http://www.ibm.com/developerworks/cn/linux/l-connector/ netlink通信机制介绍:资料来源 linux ...
- android binder 进程间通信机制5-Service注册和代理对象的获取
ServiceManager,其实也是一个Service,不过它的Server端实现并未使用Binder库的结构实现,而是直接打开binder/dev进行通信的,不具有普遍性. 下面以MediaSer ...
- android binder 进程间通信机制1-binder 驱动程序
以下内容只大概列个提纲,若要明白其中细节,还请看源码: 申明:本人菜鸟,希望得到大神指点一二,余心足已 binder 设备:/dev/binder binder 进程间通信涉及的四个角色: Clien ...
- 图文详解 Android Binder跨进程通信机制 原理
图文详解 Android Binder跨进程通信机制 原理 目录 目录 1. Binder到底是什么? 中文即 粘合剂,意思为粘合了两个不同的进程 网上有很多对Binder的定义,但都说不清楚:Bin ...
- Android Binder机制介绍
做过Android开发的同学可能有些体会,入门初期,工作内容主要是实现各式各样的UI界面,以及实现应用的业务逻辑.在这个阶段,我们会逐渐熟悉View系统,逐渐学会实现各种各样的界面以及动画效果.再往后 ...
随机推荐
- raspi串口、python串口模块pyserial
一.安装 1.下载软件包pyserial-2.7.tar.gz 网址:https://pypi.python.org/pypi/pyserial 2.8uftp上传至/usr/local/src/ ...
- Sentinel实现Redis高可用
实现目标: 一主两从,集群起始VIP在master上边,如果当前master挂了,sentinel自动选出一个slave当选master,并把VIP漂移到这台机器,然后把另一台slave指向的mast ...
- CMS - tabBar
Tips:如果网页图片(文字)看不清,请按CTRL+鼠标滚轮 1.建议使用阿里图库 或者 easyicon 2.建议使用81*81且低于40KB的图片(建议jpg) 3.如需查看脑图结构,请点击:ta ...
- Loadrunner IP欺骗
一.为什么要设置IP欺骗 1. 当某个IP的訪问过于频繁,或者訪问量过大时,server会拒绝訪问请求.这时候通过IP欺骗能够添加訪问频率和訪问量,以达到压力測试的效果. 2. 某些server配置了 ...
- Json——使用Json jar包实现Json字符串与Java对象或集合之间的互相转换
总结一下利用Json相关jar包实现Java对象和集合与Json字符串之间的互相转换: 1.创建的User类: package com.ghj.packageofdomain; public clas ...
- Android Studio代码自己主动检測错误提示
Android Studio的代码自己主动检測的错误提示方式感觉有点奇葩.和Eclipse区别非常大,Eclipse检測到某个资源文件找不到或者错误,都会在Project中相应的文件前面打叉.可是An ...
- 李洪强iOS开发之 - enum与typedef enum的用法
李洪强iOS开发之 - enum与typedef enum的用法 01 - 定义枚举类型 上面我们就在ViewController.h定义了一个枚举类型,枚举类型的值默认是连续的自然数,例如例子中的T ...
- java涉及父子类的异常
java中的异常涉及到父子类的问题,可以归纳为一句话:子类的构造函数抛出的异常必须包含父类的异常,子类的方法可以选择抛出“范围小于等于”父类的异常或不抛出异常. 1. 为什么构造函数必须抛出包含父类的 ...
- 用python编写的定向arp欺骗工具
刚学习了scapy模块的一些用法,非常强大,为了练手,利用此模块编写了一个arp欺骗工具,其核心是构造arp欺骗包.加了一个-a参数用于进行全网欺骗,先暂不实现.代码如下: #--*--coding= ...
- win7 64位安装vs2013 出现'System.AccessViolationException的错误
用管理员身份运行CMD,输入netsh winsock reset并回车(注意,必须是已管理员身份运行,这个重置LSP连接)