Android中LocalSocket使用

原文地址:http://www.cnblogs.com/bastard/archive/2012/10/09/2717052.html

一 、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
创建Framework层的服务器端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
……

下面看看这几个类之间的关系:

三、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);

<span style="font-size:14px;">native层主要代码:</span>

    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通信过程一致。


四、framework层间通信
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();
  
  ……
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值