原文地址: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层
boolean connect() { //创建socket mSocket = new LocalSocket(); //设置连接地址 LocalSocketAddress address = new LocalSocketAddress("installd",LocalSocketAddress.Namespace.RESERVED); //建立连接 mSocket.connect(address); //获取数据输入流可以读数据 mIn = mSocket.getInputStream(); //获取数据输出流可以写数据 mOut = mSocket.getOutputStream(); }
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
四、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:
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(); …… }