全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Android中socketpair双向通信详解

Android很多地方会涉及到进程间的通信,比如输入系统,那么进程间通信会涉及哪些内容呢?

1、进程:负责读取和分发事件
2、应用程序:负责处理输入事件

上面这两个进程会涉及哪些双向通信呢:

1.进程会发送输入事件
2.应用程序会告知事件处理完或APP已关闭

这里大家可能会有疑惑,binder系统能否实现上面所说的双向通信呢?

答案是不行,binder分为server和client,每次都由client主动发出请求,server收到请求后进行答复,这样的缺点就是每次请求只能单方发起,server不能主动发送数据给client,这样自然不能称为双向通信。

所以这里引入一个新的方法,叫“socketpair”

APP通过socketpair调用得到两个文件句柄,假设这两个文件句柄是fd1和fd2,这两个文件都对应有两个缓冲区(send_buf、rcv_buf),当某个进程或线程通过fd1写到他的send_buf的时候,内核里面的socket就会把send_buf里面的数据写到fd2的rcv_buf里面,另外一个线程或进程就可以读取fd2得到那些数据了,相反同理。

但是它也有缺点:由于是通过创建文件句柄来访问句柄实现的通信,那么谁可以看到这个句柄呢,只有当前APP创建出来的线程或它创建出来的子进程才能看到这些文件句柄,所以只适用于线程间通信,或者具有亲缘关系(父子进程)的进程间通信。

那么如果想使用socketpair来实现任意间的进程间的双向通信怎么办?
假设现在有APP1和APP2,这两个APP想进行任意间的进程通信,那么APP2需要得到APP1的fd2才行,怎么得到呢?可以通过binder通信,把fd2传给APP2,当然在APP2里面它就变为fd3了,这样这个任意的进程APP2就可以通过socketpair来进行通信了。这篇暂不讲解binder的实现方式

下面讲解一下“Socketpair”的程序及使用:

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>  /* See NOTES */
#include <sys/socket.h>
#define SOCKET_BUFFER_SIZE (32768U)


/* 参考:
 * frameworks\native\libs\input\InputTransport.cpp
 */

/* 线程1函数实现 */
 void *function_thread1 (void *arg)
 {
 int fd = (int)arg;/* 把文件句柄转换出来 */
 char buf[500];
 int len;
 int cnt = 0;

 while (1)
 {
 /* 向 main线程发出: Hello, main thread */
 len = sprintf(buf, "Hello, main thread, cnt = %d", cnt++);
 write(fd, buf, len);

 /* 读取数据(main线程发回的数据) */
 len = read(fd, buf, 500);
 buf[len] = '\0';
 printf("%s\n", buf);

 /* 延时5秒钟 */
 sleep(5);
 }

 return NULL;
 }



 int main(int argc, char **argv)
 {
 int sockets[2];

 /* 使用 socketpair 得到两个文件句柄到数组sockets */
 socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);

 /* 设置缓冲区, 每个文件句柄对应两个缓冲区,两个文件对应四个 */
 int bufferSize = SOCKET_BUFFER_SIZE;
 setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
 setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
 setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
 setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));

 /* 创建线程1(thread1),并把文件句柄sockets[1]传给子线程thread1 */
 pthread_t threadID;
 pthread_create(&threadID, NULL, function_thread1, (void *)sockets[1]);

 char buf[500];
 int len;
 int cnt = 0;
 int fd = sockets[0];/* 当前main函数的文件句柄是sockets[0] */


 while(1)
 {
 /* 读数据: 读线程1发出的数据 */
 len = read(fd, buf, 500);
 buf[len] = '\0';
 printf("%s\n", buf);

 /* main thread向thread1 发出: Hello, thread1 */
 len = sprintf(buf, "Hello, thread1, cnt = %d", cnt++);
 write(fd, buf, len);
 }
 }

程序非常简单,先是使用socketpair得到两个文件句柄并设置发送接收缓冲区,然后创建另一个线程,在线程中通过文件句柄读写数据到main线程中,mian也执行同样的操作实现双向通信。

测试验证:

检查是否存在这两个线程:

我们还可以修改程序,让应用程序fork出一个子进程,然后让父子进程通过socketpair来实现双向通信,比较简单,这里就不细讲了。

由于socekpair只适用于线程间通信,或者具有亲缘关系,如果想实现任意的两个进程间的双向通信就需要使用binder系统把fd传给另一个进程,这里简单说下过程,如下:

使用binder传输文件句柄:

  • 假设APP1,open某个文件句柄得到fd1
  • 通过binder驱动根据fd1得到file结构体,即files->fdt->fd[fd1]
  • 从APP2的files->fdt->fd中取出一个空项,假设是fd2,让fd2指向fd1的file结构体,即files->fdt->fd[fd2]=file
  • 之后APP1可以通过fd1,APP2可以通过fd2访问同一个文件了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# socketpair  # 双向通信  # Android 通过Messager与Service实现进程间双向通信案例详解  # Android Messenger实现进程间双向通信  # Android基于Aidl的跨进程间双向通信管理中心  # Android Socket 线程连接openwrt与arduino单片机串口双向通信的实例解析  # Android binder 匿名服务实现双向通信的解决方案  # 句柄  # 这两个  # 可以通过  # 应用程序  # 适用于  # 写到  # 来实现  # 就可以  # 会有  # 还可以  # 就不  # 可以看到  # 另外一个  # 会把  # 这篇  # 才行  # 涉及到  # 它就  # 讲了  # 它也 


相关文章: 制作网站外包平台,自动化接单网站有哪些?  建站之星如何快速更换网站模板?  C++用Dijkstra(迪杰斯特拉)算法求最短路径  已有域名和空间如何搭建网站?  网站制作难吗安全吗,做一个网站需要多久时间?  阿里云网站制作公司,阿里云快速搭建网站好用吗?  安云自助建站系统如何快速提升SEO排名?  如何选择可靠的免备案建站服务器?  建站之星展会模版如何一键下载生成?  山东云建站价格为何差异显著?  上海网站制作网站建设公司,建筑电工证网上查询系统入口?  如何快速搭建高效WAP手机网站?  Bpmn 2.0的XML文件怎么画流程图  如何确认建站备案号应放置的具体位置?  如何在万网主机上快速搭建网站?  PHP 500报错的快速解决方法  整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?  建站之星导航如何优化提升用户体验?  微课制作网站有哪些,微课网怎么进?  制作旅游网站html,怎样注册旅游网站?  如何通过可视化优化提升建站效果?  网站制作多少钱一个,建一个论坛网站大约需要多少钱?  建站之星如何保障用户数据免受黑客入侵?  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  c# 在高并发场景下,委托和接口调用的性能对比  如何配置IIS站点权限与局域网访问?  如何在建站宝盒中设置产品搜索功能?  家具网站制作软件,家具厂怎么跑业务?  如何在腾讯云免费申请建站?  ,柠檬视频怎样兑换vip?  网站代码制作软件有哪些,如何生成自己网站的代码?  Swift中循环语句中的转移语句 break 和 continue  成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?  c# F# 的 MailboxProcessor 和 C# 的 Actor 模型  如何做静态网页,sublimetext3.0制作静态网页?  官网网站制作腾讯审核要多久,联想路由器newifi官网  网站制作新手教程,新手建设一个网站需要注意些什么?  建站之星CMS建站配置指南:模板选择与SEO优化技巧  如何快速上传自定义模板至建站之星?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?  网站制作的步骤包括,正确网址格式怎么写?  如何在腾讯云服务器快速搭建个人网站?  Python如何创建带属性的XML节点  C++时间戳转换成日期时间的步骤和示例代码  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  网站制作话术技巧,网站推广做的好怎么话术?  测试制作网站有哪些,测试性取向的权威测试或者网站?  如何高效利用亚马逊云主机搭建企业网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。