Android中LocalSocket使用
一 Socket
Socket最初用在基于TCP/IP网络间进程通信中,以客户端/服务器模式进行通信。
实现异步操作,共享资源集中处理,提高客户端响应能力。
Tcp通信基本流程:
服务器端 客户端
1.创建socket 1.创建socket
2.bind()
3.listen()
4.accecp()
----等待客户端连接---- 2.connect()
5.读数据(recv) 3.写数据(send)
6.写数据(send) 4.读数据(recv)
7.关闭socket(closesocket()) 5.关闭socket(closesocket())
数据流:
二 Android LocalSocket
LocalSocket
在Unix域名空间创建一个套接字(非服务端)。
是对Linux中Socket进行了封装,采用JNI方式调用,实现进程间通信。
具体就是Native层Server和Framework层Client之间进行通信,或在各层次中能使用Client/Server模式实现通信。
LocalServerSocket
创建服务器端Unix域套接字,与LocalSocket对应。
LocalSocketImpl
Framework层Socket的实现,通过JNI调用系统socket API。
LocalSocketAddress
Unix域socket的地址以及所处的空间。
JNI访问接口:\frameworks\base\core\jni\android_net_LocalSocketImpl.cpp
socket_create
socket_connect_local
socket_bind_local
socket_listen
……
下面看看这几个类之间的关系:
使用Android的LocalSocket建立socket通信,是基于网络socket过程一致的。
三 native与framework之间的通信
以install这个服务为例:
1 增加socket资源
\system\core\rootdir\init.rc中:
service installd /system/bin/installd
class main
socket installd stream 600 system system
在启动install服务时,就会为install分配socket文件系统资源:dev/socket/installd
Install服务的Socket资源和名称installd绑定起来。
这些都是在开机初始化化init进程中启动service时完成:
service_start
create_socket
publish_socket
2 native层
install进程 建立服务端程序
native 层中作为server:\frameworks\base\cmds\installd\installd.c
int main(const int argc, const char *argv[]) {//获取已绑定socketlsocket = android_get_control_socket(SOCKET_PATH);//监听socketlisten(lsocket, 5);for (;;) {//等待客户端建立连接s = accept(lsocket, &addr, &alen);for (;;) {//接收数据 相当于recv readx(s, buf, count);//执行相关的操作 execute(s, buf);}//关闭socket close(s);} }
3 framework层
客户端程序:
\frameworks\base\services\java\com\android\server\pm\Installer.java
boolean connect() {//创建socketmSocket = new LocalSocket();//设置连接地址LocalSocketAddress address = new LocalSocketAddress("installd",LocalSocketAddress.Namespace.RESERVED);//建立连接 mSocket.connect(address);//获取数据输入流 可以读数据mIn = mSocket.getInputStream();//获取数据输出流 可以写数据mOut = mSocket.getOutputStream(); }
因此以native层service与framework建立client/server模式socket通信主要代码:
java层主要代码:
LocalSocket s =null;LocalSocketAddress l;s = new LocalSocket();l = new LocalSocketAddress(SOCKET_NAME,LocalSocketAddress.Namespace.RESERVED);s.connect(l);
native层主要代码:
s_fdListen = android_get_control_socket(SOCKET_NAME);ret = listen(s_fdListen, n);s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
init.rc中加入:
service myserver /system/bin/myserverclass mainsocket myserver stream 600 system system……
当然建立这种client/server模式并不一定要在native层和framework层,仅在framework层也能够进行。
系统提供了LocalSocket作为客户端使用,同时提供了LocalServerSocket作为服务端使用。
Zygote服务使用了LocalServerSocket作为服务端socket通信。
建立socket通信,也可以在代码执行过程中进行,使用LocalSocket与LocalServerSocket。
在init.rc中为服务端建立的socket资源和初始化时绑定,与在代码中使用LocalServerSocket
建立的服务端socket资源在Linux域空间不同而已,过程是一样的跟一般的socket通信过程一致。
四 LocalSocket与LocalServerSocket建立socket通信
LocalSocket就是作为客户端建立于服务端的连接,发送数据。
LocalServerSocket作为服务端使用,建立socket监听客户端请求。通过构造函数看到有两种方式:
在Linux抽象空间 创建一个新的服务端socket:
public LocalServerSocket(String name) throws IOException {//创建socket资源impl = new LocalSocketImpl();impl.create(true);//绑定地址localAddress = new LocalSocketAddress(name);impl.bind(localAddress);//监听 impl.listen(LISTEN_BACKLOG); }
用文件描述符创建已经存在并且绑定的服务端socket:
如在init.rc中指定socket资源 dev/socket/……,zygote使用此方式创建作为服务端的socket
LocalServerSocket socket = new LocalServerSocket(createFileDescriptor(fileDesc));
public LocalServerSocket(FileDescriptor fd) throws IOException {//已绑定 监听impl = new LocalSocketImpl(fd);impl.listen(LISTEN_BACKLOG);localAddress = impl.getSockAddress(); }
通常使用过程中:
客户端代码:
String message;//创建socket LocalSocket sender = new LocalSocket();//建立对应地址连接 sender.connect(new LocalSocketAddress(SOCKET_ADDRESS));//发送写入数据 sender.getOutputStream().write(message.getBytes());//关闭socket sender.getOutputStream().close();
服务端:
//创建socket并绑定监听 新创建的 LocalServerSocket server = new LocalServerSocket(SOCKET_ADDRESS); while (true) {//等待建立连接LocalSocket receiver = server.accept(); //接收获取数据流InputStream input = receiver.getInputStream(); …… }
参考文档:
http://hi.baidu.com/leoispace/item/ab4a271e6624824b6926bbe9
http://www.cnblogs.com/over140/archive/2011/11/22/2258372.html
http://blog.csdn.net/jamin0107/article/details/6832159
Android中LocalSocket使用相关推荐
- Android中LocalSocket(套接字)使用
今天在看<Android框架揭秘>的第5章<Zygote>时,Zygote在初始化时,会调用registerZygoteSocket()来接收新的Android应用程序运行的请 ...
- Android 系统(272)---Android中的各种保活
Android中的各种保活 目前市面上的应用,貌似除了微信和手Q都会比较担心被用户或者系统(厂商)杀死问题.本文对 Android 进程拉活进行一个总结. Android 进程拉活包括两个层面: A. ...
- 从源码解析-Android中Zygote进程是如何fork一个APP进程的
zygote进程fork子进程 前言 强烈推荐 进程创建流程 APP启动第三方应用 startActivity startService sendBroadcast ContentResolver.q ...
- Android中SeLinux权限 .te文件编写
在android中添加一个LocalSocket通信,权限部分折腾了好几天,终于搞定了. 首先在root权限下使用setenforce 0命令放开selinux权限,看看需要的操作是否能成功.如果可以 ...
- Android中实现为TextView添加多个可点击的文本
这篇文章主要介绍了Android中实现为TextView添加多个可点击的文本,可实现类似Android社交软件显示点赞用户并通过用户名称进入该用户主页的功能,是非常实用的技巧,需要的朋友可以参考下.具 ...
- android 弹出fragment,Android中ViewPager获取当前显示的Fragment
前言 在项目中,有时会用到在ViewPager中显示同样类型的Fragment,同时这样的Fragment的个数是动态的,但是PagerAdapter没有给我们提供getCurrentFragment ...
- android 读取内部存储文件格式,Android中的数据储存之文件存储
当我们在使用各种程序时,其实际上是在和各种数据打交道,当我们聊QQ,刷微博,看新闻,其实都是在和里面的数据交互 例如在聊天时发出的消息,以及在登录时输入的账号密码,其实都是瞬时数据,那什么是瞬时数据呢 ...
- android中一种不支持的lua操作
今天写了一段lua代码,在win32中正常运行,在android中运行无效. 大概是这样的: ------file1.lua----- local t = {} t.str = "this ...
- Android中对Log日志文件的分析[转]
一,Bug出现了, 需要"干掉"它 bug一听挺吓人的,但是只要你懂了,android里的bug是很好解决的,因为android里提供了LOG机制,具体的底层代码,以后在来分析,只 ...
最新文章
- UIPageViewController教程
- (13)[Xamarin.Android] 不同分辨率下的图片使用概论
- qq掉线咒语:aidusort.as
- Non-resolvable parent POM
- java重写6,java重写equals()方法和hashCode()方法
- highgui java opencv_OpenCV在C Qt应用程序中的highgui
- linux下启动tomcat,Cannot find setclasspath.sh
- 最让人心动的十大互联网界广告语+超笑评语
- oracle 分组统计行数,求助分组之后进行统计行数
- 20191201每日一句
- 基于Java+SpringBoot+vue+elementui农产品物流系统详细设计实现
- 扣扣机器人唱歌_qq小冰机器人唱歌脚本-qq群机器人小冰无限唱歌插件下载v6.7.1 安卓版-腾牛安卓网...
- 再忆年少,再见年少——青春路上的我们
- 如何批量新建文件夹,批量新建文件夹并命名
- 无线中DNS改为114.114.114.114真的能提高网速吗?如何提高网速?
- python中 math模块下 atan 和 atan2的区别
- 自动化构建:gitlab gitlab-run ,maven的缓存 和 gitea drone drone-run
- 【渝粤教育】电大中专电商运营实操 (21)作业 题库
- Android中Manifest.xml配置文件
- 半世纪以来最佳英文小说:《英国病人》