• 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[]) 
    {
        //获取已绑定socket
        lsocket = android_get_control_socket(SOCKET_PATH);
    
        //监听socket
        listen(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() 
    {
           //创建socket
           mSocket = 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/myserver
           class main
           socket 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

  • 相关阅读:
    Vuejs
    Vuejs
    Vuejs
    Vuejs
    JS高级之面试必须知道的几个点
    用vue快速开发app的脚手架工具
    作为一名前端开发工程师,你必须掌握的WEB模板引擎:Handlebars
    REST接口设计规范总结
    eclipse实现JavaWeb应用增量打包
    转载:作为面试官,我是怎么快速判断程序员能力的?
  • 原文地址:https://www.cnblogs.com/bastard/p/2717052.html
Copyright © 2020-2023  润新知