java local socket_Android中LocalSocket使用

本文详细介绍了Android中的LocalSocket和LocalServerSocket,它们用于实现进程间通信。LocalSocket作为客户端连接服务端,而LocalServerSocket用于创建服务端监听。文章通过实例展示了如何在native层和framework层之间建立socket通信,并讨论了在不同场景下使用这两种类型的socket。
摘要由CSDN通过智能技术生成

一 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())

数据流:

f07e4c0c39fdeeb01f936f31ab2f1eca.png

二 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

……

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

e9ea7ee1c16e301a8c59a51cf4d36be6.png

使用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 = newLocalSocket();//设置连接地址

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= newLocalSocket();

l= newLocalSocketAddress(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/myserverclassmain

socket myserver stream600system 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:

publicLocalServerSocket(String name) throws IOException

{//创建socket资源

impl = newLocalSocketImpl();

impl.create(true);//绑定地址

localAddress = newLocalSocketAddress(name);

impl.bind(localAddress);//监听

impl.listen(LISTEN_BACKLOG);

}

用文件描述符创建已经存在并且绑定的服务端socket:

如在init.rc中指定socket资源 dev/socket/……,zygote使用此方式创建作为服务端的socket

LocalServerSocket socket = new LocalServerSocket(createFileDescriptor(fileDesc));

publicLocalServerSocket(FileDescriptor fd) throws IOException

{//已绑定 监听

impl = newLocalSocketImpl(fd);

impl.listen(LISTEN_BACKLOG);

localAddress=impl.getSockAddress();

}

通常使用过程中:

客户端代码:

String message;//创建socket

LocalSocket sender = newLocalSocket();//建立对应地址连接

sender.connect(newLocalSocketAddress(SOCKET_ADDRESS));//发送写入数据

sender.getOutputStream().write(message.getBytes());//关闭socket

sender.getOutputStream().close();

服务端:

//创建socket并绑定监听 新创建的

LocalServerSocket server = newLocalServerSocket(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、付费专栏及课程。

余额充值