一 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使用相关推荐

  1. Android中LocalSocket(套接字)使用

    今天在看<Android框架揭秘>的第5章<Zygote>时,Zygote在初始化时,会调用registerZygoteSocket()来接收新的Android应用程序运行的请 ...

  2. Android 系统(272)---Android中的各种保活

    Android中的各种保活 目前市面上的应用,貌似除了微信和手Q都会比较担心被用户或者系统(厂商)杀死问题.本文对 Android 进程拉活进行一个总结. Android 进程拉活包括两个层面: A. ...

  3. 从源码解析-Android中Zygote进程是如何fork一个APP进程的

    zygote进程fork子进程 前言 强烈推荐 进程创建流程 APP启动第三方应用 startActivity startService sendBroadcast ContentResolver.q ...

  4. Android中SeLinux权限 .te文件编写

    在android中添加一个LocalSocket通信,权限部分折腾了好几天,终于搞定了. 首先在root权限下使用setenforce 0命令放开selinux权限,看看需要的操作是否能成功.如果可以 ...

  5. Android中实现为TextView添加多个可点击的文本

    这篇文章主要介绍了Android中实现为TextView添加多个可点击的文本,可实现类似Android社交软件显示点赞用户并通过用户名称进入该用户主页的功能,是非常实用的技巧,需要的朋友可以参考下.具 ...

  6. android 弹出fragment,Android中ViewPager获取当前显示的Fragment

    前言 在项目中,有时会用到在ViewPager中显示同样类型的Fragment,同时这样的Fragment的个数是动态的,但是PagerAdapter没有给我们提供getCurrentFragment ...

  7. android 读取内部存储文件格式,Android中的数据储存之文件存储

    当我们在使用各种程序时,其实际上是在和各种数据打交道,当我们聊QQ,刷微博,看新闻,其实都是在和里面的数据交互 例如在聊天时发出的消息,以及在登录时输入的账号密码,其实都是瞬时数据,那什么是瞬时数据呢 ...

  8. android中一种不支持的lua操作

    今天写了一段lua代码,在win32中正常运行,在android中运行无效. 大概是这样的: ------file1.lua----- local t = {} t.str = "this ...

  9. Android中对Log日志文件的分析[转]

    一,Bug出现了, 需要"干掉"它 bug一听挺吓人的,但是只要你懂了,android里的bug是很好解决的,因为android里提供了LOG机制,具体的底层代码,以后在来分析,只 ...

最新文章

  1. UIPageViewController教程
  2. (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  3. qq掉线咒语:aidusort.as
  4. Non-resolvable parent POM
  5. java重写6,java重写equals()方法和hashCode()方法
  6. highgui java opencv_OpenCV在C Qt应用程序中的highgui
  7. linux下启动tomcat,Cannot find setclasspath.sh
  8. 最让人心动的十大互联网界广告语+超笑评语
  9. oracle 分组统计行数,求助分组之后进行统计行数
  10. 20191201每日一句
  11. 基于Java+SpringBoot+vue+elementui农产品物流系统详细设计实现
  12. 扣扣机器人唱歌_qq小冰机器人唱歌脚本-qq群机器人小冰无限唱歌插件下载v6.7.1 安卓版-腾牛安卓网...
  13. 再忆年少,再见年少——青春路上的我们
  14. 如何批量新建文件夹,批量新建文件夹并命名
  15. 无线中DNS改为114.114.114.114真的能提高网速吗?如何提高网速?
  16. python中 math模块下 atan 和 atan2的区别
  17. 自动化构建:gitlab gitlab-run ,maven的缓存 和 gitea drone drone-run
  18. 【渝粤教育】电大中专电商运营实操 (21)作业 题库
  19. Android中Manifest.xml配置文件
  20. 半世纪以来最佳英文小说:《英国病人》

热门文章

  1. 表单提交Post方法、Get方法
  2. Centos/Linux下如何查看网关地址/Gateway地址
  3. hibernateTemplate 的find 查找方法
  4. Linux下ARP相关操作
  5. linux系统启动故障排除
  6. Kubernetes学习笔记之Calico CNI Plugin源码解析(一)
  7. Channels In Go
  8. java常用的正则表达式
  9. 微信小程序字符长度超出变成神略号显示
  10. 使用netty实现聊天室功能