Local Socket

LocalSocket

 在Unix域名空间创建一个套接字(非服务端)。
  是对Linux中Socket进行了封装,采用JNI方式调用,实现进程间通信。
  具体就是Native层Server和Framework层Client之间进行通信,或在各层次中能使用Client/Server模式实现通信。

LocalServerSocket

  创建服务器端Unix域套接字,与LocalSocket对应。
  

LocalSocketImpl

Framework层Socket的实现,通过JNI调用系统socket API。

JNI访问接口:
\frameworks\base\core\jni\android_net_LocalSocketImpl.cpp

socket_create

socket_connect_local

socket_bind_local

socket_listen

增加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时完成:

        for (si = svc->sockets; si; si = si->next) {
            int socket_type = (
                    !strcmp(si->type, "stream") ? SOCK_STREAM :
                        (!strcmp(si->type, "dgram") ? SOCK_DGRAM : SOCK_SEQPACKET));
            int s = create_socket(si->name, socket_type,
                                  si->perm, si->uid, si->gid);
            if (s >= 0) {
                publish_socket(si->name, s);
            }
        }
native层

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);
    }
}             
class FrameworkListener : public SocketListener {
public:
    static const int CMD_ARGS_MAX = 16;
private:
    FrameworkCommandCollection *mCommands;

public:
    FrameworkListener(const char *socketName);
    virtual ~FrameworkListener() {}

protected:
    void registerCmd(FrameworkCommand *cmd);
    virtual bool onDataAvailable(SocketClient *c);

private:
    void dispatchCommand(SocketClient *c, char *data);
};
bool FrameworkListener::onDataAvailable(SocketClient *c) {
    char buffer[255];
    int len;

    if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) {
        SLOGE("read() failed (%s)", strerror(errno));
        return errno;
    } else if (!len)
        return false;

    int offset = 0;
    int i;

    for (i = 0; i < len; i++) {
        if (buffer[i] == '\0') {
            dispatchCommand(c, buffer + offset);
            offset = i + 1;
        }
    }
    return true;
}
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();
}
以下是一个简单的安卓10版本以上的local socket服务端和客户端代码。请注意,以下代码仅供参考,并未进行完整的测试和验证,不保证完全正确和可用。 服务端代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define SOCK_PATH "/data/data/com.example.sockettest/mysocket" int main() { int server_fd, client_fd; int len; struct sockaddr_un server_addr, client_addr; char buf[256]; // 创建套接字 if ((server_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(EXIT_FAILURE); } // 绑定地址 server_addr.sun_family = AF_LOCAL; strcpy(server_addr.sun_path, SOCK_PATH); unlink(server_addr.sun_path); len = strlen(server_addr.sun_path) + sizeof(server_addr.sun_family); if (bind(server_fd, (struct sockaddr *)&server_addr, len) == -1) { perror("bind"); exit(EXIT_FAILURE); } // 监听连接 if (listen(server_fd, 5) == -1) { perror("listen"); exit(EXIT_FAILURE); } // 接受连接 socklen_t client_len = sizeof(client_addr); if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) == -1) { perror("accept"); exit(EXIT_FAILURE); } // 接收数据 while (1) { int num_bytes = recv(client_fd, buf, sizeof(buf), 0); if (num_bytes == -1) { perror("recv"); exit(EXIT_FAILURE); } else if (num_bytes == 0) { printf("Connection closed\n"); break; } printf("Received: %s", buf); } // 关闭连接 close(client_fd); close(server_fd); unlink(server_addr.sun_path); return 0; } ``` 客户端代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define SOCK_PATH "/data/data/com.example.sockettest/mysocket" int main() { int client_fd; struct sockaddr_un server_addr; char *buf = "Hello, world!\n"; // 创建套接字 if ((client_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(EXIT_FAILURE); } // 连接服务器 server_addr.sun_family = AF_LOCAL; strcpy(server_addr.sun_path, SOCK_PATH); int len = strlen(server_addr.sun_path) + sizeof(server_addr.sun_family); if (connect(client_fd, (struct sockaddr *)&server_addr, len) == -1) { perror("connect"); exit(EXIT_FAILURE); } // 发送数据 if (send(client_fd, buf, strlen(buf), 0) == -1) { perror("send"); exit(EXIT_FAILURE); } // 关闭连接 close(client_fd); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值