当前位置: 首页 > news >正文

Android跨进程通信,IPC,RPC,Binder系统,C语言应用层调用

文章目录

  • Android跨进程通信,IPC,RPC,Binder系统,C语言应用层调用()
    • 1.概念
    • 2.流程
    • 3.bctest.c
      • 3.1 注册服务,打开binder驱动
      • 3.2 获取服务
    • 4.binder_call

Android跨进程通信,IPC,RPC,Binder系统,C语言应用层调用()

1.概念

IPC,进程间通信,a进程发送数据给b进程,就是跨进程通信。

RPC,远程调用,a进程想打开led,点亮led,调用led_open函数,通过IPC发送数据给b进程,b取出数据,然后调用b进程的led_open函数,看似a进程来直接操作led_open函数一样,实际上是a发送数据给b,b操作硬件

b进程服务端程序要先向servicemanager注册服务,a进程查询led_服务,得到一个handle,指向进程b。

数据一般存在char buf[1024]里面。a,b进程通过buffer传递数据双端。

谷歌的源码参考目录

在这里插入图片描述

binder.c(谷歌封装好的c函数)

2.流程

servicemanager先由系统先运行,

  1. open binder驱动
  2. 告诉驱动程序自己就是servicemanager
  3. while(1)循环,读数据,读取驱动,获取数据,没有数据就休眠,得到数据就解析数据。
    • 服务端注册服务,在链表中记录服务名,
    • 客户端获取服务,查询链表中的服务,返回服务端进程

服务端程序:

  1. open驱动
  2. 注册服务,向servicemanager发送服务的名字,
  3. while(1)读驱动,无数据就休眠,解析数据,调用系统对应的底层函数,

客户端程序:

  1. open驱动。
  2. 获取服务,向servicemanager查询服务,获得一个handle,
  3. 向handle句柄发送数据。

打开驱动程序

在这里插入图片描述

告诉驱动程序自己就是servicemanager

在这里插入图片描述

循环读取数据,

在这里插入图片描述

binder_loop读数据,

在这里插入图片描述

解析数据

在这里插入图片描述

处理回复信息给客户端

在这里插入图片描述

客户端获取服务

在这里插入图片描述

注册服务

在这里插入图片描述

3.bctest.c

3.1 注册服务,打开binder驱动

在这里插入图片描述

注册服务,构造好数据

在这里插入图片描述

发给目标target

在这里插入图片描述

我们看一下这个值

在这里插入图片描述

在头文件中定义,句柄是0,进程间通信,0就是servicemanager进程,

在这里插入图片描述

通过binder_call调用,code: 表示要调用servicemanager中的"addservice"函数

3.2 获取服务

打开驱动, 循环查询服务列表

在这里插入图片描述

if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
return 0;

还是调用binder_call函数,msg中含有你想获取服务的名字,含有servicemanager回复的数据,

4.binder_call

实现远程调用, 向谁发数据,

target,目的进程

code,调用的函数

msg,提供的数据参数

reply,返回值

构造我们要发送的数据,放在buffer中,用binder_io

调用ioctl发送数据。

int binder_call(struct binder_state *bs,struct binder_io *msg, struct binder_io *reply,uint32_t target, uint32_t code)
{int res;struct binder_write_read bwr;struct {uint32_t cmd;struct binder_transaction_data txn;} __attribute__((packed)) writebuf;unsigned readbuf[32];if (msg->flags & BIO_F_OVERFLOW) {fprintf(stderr,"binder: txn buffer overflow\n");goto fail;}writebuf.cmd = BC_TRANSACTION;writebuf.txn.target.handle = target;writebuf.txn.code = code;writebuf.txn.flags = 0;writebuf.txn.data_size = msg->data - msg->data0;writebuf.txn.offsets_size = ((char*) msg->offs) - ((char*) msg->offs0);writebuf.txn.data.ptr.buffer = (uintptr_t)msg->data0;writebuf.txn.data.ptr.offsets = (uintptr_t)msg->offs0;bwr.write_size = sizeof(writebuf);bwr.write_consumed = 0;bwr.write_buffer = (uintptr_t) &writebuf;hexdump(msg->data0, msg->data - msg->data0);for (;;) {bwr.read_size = sizeof(readbuf);bwr.read_consumed = 0;bwr.read_buffer = (uintptr_t) readbuf;//调用ioctl发送数据。bwr结构体res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);if (res < 0) {fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno));goto fail;}res = binder_parse(bs, reply, (uintptr_t) readbuf, bwr.read_consumed, 0);if (res == 0) return 0;if (res < 0) goto fail;}fail:memset(reply, 0, sizeof(*reply));reply->flags |= BIO_F_IOERROR;return -1;
}

在这里插入图片描述

数据要转换,binder_io参数是这个类型,内核驱动要求res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);bwr是上图的类型。

ioctl收数据,也会收到binder_write_read,然后转化为binder_io

svcmgr_lookup看下面源码

uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
{uint32_t handle;//binder_io对缓冲区的管理unsigned iodata[512/4];//初始化结构体binder_iostruct binder_io msg, reply;//初始化就可以在缓冲池里面放数据 了bio_init(&msg, iodata, sizeof(iodata), 4);bio_put_uint32(&msg, 0);  // strict mode headerbio_put_string16_x(&msg, SVC_MGR_NAME);bio_put_string16_x(&msg, name);//binder_io发送给驱动if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))return 0;handle = bio_get_ref(&reply);if (handle)binder_acquire(bs, handle);binder_done(bs, &msg, &reply);return handle;
}

相关文章:

  • 【Qt之QStandardItemModel】使用,tableview、listview、treeview设置模型
  • 【C++】【Opencv】cv::warpAffine()仿射变换函数详解,实现平移、缩放和旋转等功能
  • ChatGPT简介及基本概念
  • 吴恩达《机器学习》8-5->8-6:特征与直观理解I、样本与值观理解II
  • 【我和Python算法的初相遇】——体验递归的可视化篇
  • 拍照小白入坑
  • Android VSYNC发展历程
  • es的优势
  • Lec14 File systems 笔记
  • 前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章 —— 第一章 技术栈简介
  • 奇瑞金融——汽车金融行业架构设计
  • 无线WiFi安全渗透与攻防(六)之WEP破解-Gerix-wifi-cracker自动化破解WEP加密
  • 让文字在盒子中水平居中与垂直居中
  • 6.9平衡二叉树(LC110-E)
  • RT-Thread STM32F407 BMI088--SPI
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • Angular 4.x 动态创建组件
  • centos安装java运行环境jdk+tomcat
  • extjs4学习之配置
  • iOS 颜色设置看我就够了
  • Java多态
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • Python利用正则抓取网页内容保存到本地
  • QQ浏览器x5内核的兼容性问题
  • STAR法则
  • ViewService——一种保证客户端与服务端同步的方法
  • 从零开始学习部署
  • 复杂数据处理
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 聊聊hikari连接池的leakDetectionThreshold
  • 前端设计模式
  • 整理一些计算机基础知识!
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​插件化DPI在商用WIFI中的价值
  • ​决定德拉瓦州地区版图的关键历史事件
  • ​人工智能书单(数学基础篇)
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • $GOPATH/go.mod exists but should not goland
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)windows配置JDK环境
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (六)c52学习之旅-独立按键
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (四) 虚拟摄像头vivi体验
  • (译)2019年前端性能优化清单 — 下篇
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)母版页和相对路径
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .Net(C#)自定义WinForm控件之小结篇