打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
LocalSocket实现进程间通信

android下使用localsocket可以实现C与C,C与JAVA,JAVA与JAVA进程间通信。
localsocket是linux下的一种本地套接字,用来进行进程间通信,分为非命名和命名两种类型,非命名本地套接字只能用在父子进程之间通信(其实是只有保存了未命名的套接字的文件描述符的进程可以使用),命名套接字则没有这个限制。android在linux的本地套接字上进行封装。
android上使用localsocket主要是通过name来区分,也就是说客户端和服务端之间连接必须使用相同的name,并且一个name同一时间只能有一个服务端运行,name可以只一串字符串,如“com.penguin.sk”。

  • c 客户端
  • c 服务端
  • java 客户端
  • java 服务端

c 客户端

c客户端代码主要调用的是android接口:
int socket_local_server(const char *name, int namespaceId, int type)
函数读写id,read id就是接收服务端的数据,write id就是发送数据给服务端– 参数name就是上述说的客户端与服务端连接的关键name,namespaceId一般使用ANDROID_SOCKET_NAMESPACE_ABSTRACT, type 使用SOCK_STREAM。下面是客户端c demon代码:

#include <sys/socket.h>#include <sys/un.h>#include <stddef.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <cutils/sockets.h>#define PATH "com.penghui.localsocket"int main(int argc, char *argv[]) {    int socketID;    int ret;    int i = 0;    int len = 0;    for(;i < argc ;i++){        len = len + strlen(argv[i]);    }    len = len + argc ;    char *buffer ;    buffer = ( char *)malloc(len * sizeof( char *));    if(buffer == NULL){        printf("malloc failed\n");        return 0;    }    strcpy(buffer, argv[0]);    for(i=1;i<argc;i++){        strcat(buffer, " ");         strcat(buffer, argv[i]);     }    socketID = socket_local_client(PATH, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);    if (socketID < 0)    {        return socketID;    }    ret = write(socketID, buffer, strlen(buffer));    if(ret < 0){        printf("send failed\n");        return ret;    }    char buf2[512] = {0};    ret = read(socketID,buf2,sizeof(buf2));    if(ret < 0){        printf("recived failed\n");        return ret;    }else{        printf("c client recived from server: %s\n",buf2);    }    ret = close(socketID);    if (ret < 0)    {        return ret;    }    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

c 服务端

c服务端调用
int socket_local_server(const char *name, int namespace, int type)
函数返回服务端socket,然后可以调用accept开始接受客户端请求,参数与客户端一样

#include <sys/socket.h>#include <sys/un.h>#include <stddef.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <cutils/sockets.h>#include <pthread.h>#define PATH "com.penghui.localsocket"void * connectThread(void *arg);int main(int argc, char *argv[]){    int ret ;    int serverID = socket_local_server(PATH, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);    if(serverID < 0){        printf("socket_local_server failed :%d\n",serverID);        return serverID;    }    int socketID;    pthread_t tid;    while((socketID= accept(serverID,NULL,NULL)) >=0){        ret = pthread_create(&tid,NULL,connectThread,(void *)&socketID);         if(ret != 0){            printf("error create thread:%s\n",strerror(ret));            exit(1);        }    }    return ret;}void * connectThread(void *arg){    int ret;    int socketID =*(int *)arg;    if(socketID < 0){        printf("socketID is %d\n",socketID);        return NULL;    }    char buf2[512] = {0};    ret = read(socketID,buf2,sizeof(buf2));    if(ret < 0){        printf("recived failed\n");        return NULL;    }    printf("c server recived: %s\n",buf2);    char buffer[]  = {"this message from c server "};    ret = write(socketID, buffer, strlen(buffer));    if(ret < 0){        printf("write failed\n");        return NULL;    }    close(socketID);    return NULL;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

java 客户端

java 的服务端和客户端和网络socket基本一样,只不过网络socket是用ip和端口号连接的,localsocket使用上述说的name。
客户端代码是在android源码下编译成jar包,然后仿造android am命令(frameworks/base/cmds/am/)在clientSocket脚本里调用jar包做成可执行文件的,这种做法对jar包的包名有要求,最好是直接用com.android.commands.*开头的。

package com.android.commands.factory;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import android.net.LocalSocket;import android.net.LocalSocketAddress;import android.util.Log;public class Factory {    private static final String TAG= "Factory_test";    public static void main(String[] args){        if(args.length == 0 ){            printHelp();            return ;        }        String command = "";            for(int i = 0;i < args.length; i++){            command = command + args[i] + " ";            Log.w(TAG,"command"+command);        }        ClientConnect cl = new ClientConnect();        cl.connect();        cl.send(command);        String result = cl.recv();        System.out.println("java client recive:"+result);        cl.close();    }    private static void printHelp(){        System.out.println(                "\n"                                                        +                "Usage: factory_test cmds [params]\n"                       +                "cmds:\n"                                                   +                "        get_eth_mac -- get ethernet mac address.\n"        +                "        copy_log -- copy the log to usb device .\n"                                                                                    );    }}class ClientConnect {          private static final String TAG = "ClientConnect";          private static final String name = "com.penghui.localsocket";          private LocalSocket Client = null;          private PrintWriter os = null;          private BufferedReader is = null;          private int timeout = 30000;          public void connect(){                try {                  Client = new LocalSocket();                  Client.connect(new LocalSocketAddress(name));                 // Client.setSoTimeout(timeout);              } catch (IOException e) {                  e.printStackTrace();              }          }          public void send(String data) {              try {                  os = new PrintWriter(Client.getOutputStream());                  os.println(data);                  os.flush();                  //System.out.println("client send over");              } catch (IOException e) {                  e.printStackTrace();              }          }          public String recv() {              Log.d(TAG,"recv");              String result = null;              try {                  is = new BufferedReader(new InputStreamReader(Client.getInputStream()));                  result = is.readLine();                  Log.d(TAG, result);              } catch (IOException e) {                  e.printStackTrace();              } finally {              }              return result;          }          public void close() {              try {                  is.close();                  os.close();                  Client.close();              } catch (IOException e) {                  e.printStackTrace();              }          }      }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

Android.mk

# Copyright 2008 The Android Open Source Project#LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES := $(call all-subdir-java-files)LOCAL_MODULE := factoryinclude $(BUILD_JAVA_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := clientSocketJavaLOCAL_SRC_FILES := clientSocketLOCAL_MODULE_CLASS := EXECUTABLESLOCAL_MODULE_TAGS := optionalinclude $(BUILD_PREBUILT)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

clientSocket 脚本

#!/system/bin/sh## Script to start "" on the device, which has a very rudimentary# shell.#base=/systemexport CLASSPATH=$base/framework/factory.jarexec app_process $base/bin com.android.commands.factory.Factory "$@"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

java 服务端

java服务端实现在一个apk里,apk启动时开启服务端,然后就可以执行客户端命令去与服务端交互数据。

package com.example.localsocketserver;import java.io.BufferedReader;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import android.app.Activity;import android.net.Credentials;import android.net.LocalServerSocket;import android.net.LocalSocket;import android.net.LocalSocketAddress;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;public class MainActivity extends Activity {    private static final String TAG = "MainActivity";    private ServerThread mThread = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        startServer();    }    @Override    protected void onPause() {        // TODO Auto-generated method stub        super.onPause();    }    @Override    protected void onDestroy() {        // TODO Auto-generated method stub        super.onDestroy();        stopServer();    }    private void startServer(){        stopServer();        mThread = new ServerThread();        mThread.start();    }    private void stopServer(){        if(mThread != null){            mThread.exit();            mThread = null;        }    }    private class ServerThread extends Thread{        private boolean exit = false;        private int port = 3333;        public void run() {              LocalServerSocket server = null;              BufferedReader mBufferedReader = null;              PrintWriter os = null;              String readString =null;              try {                  server = new LocalServerSocket("com.repackaging.localsocket");                        while (!exit) {                      LocalSocket connect = server.accept();                      Credentials cre = connect.getPeerCredentials();                    Log.i(TAG,"accept socket uid:"+cre.getUid());                     new ConnectThread(connect).start();                }                 } catch (IOException e) {                  e.printStackTrace();              }finally{                try {                      mBufferedReader.close();                      os.close();                      server.close();                  } catch (IOException e) {                      e.printStackTrace();                  }              }          }         public void exit(){            exit = true;            this.interrupt();            try {                this.wait();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }    class ConnectThread extends Thread{        LocalSocket socket = null;         BufferedReader mBufferedReader = null;           InputStream input = null;         PrintWriter os = null;         String readString =null;        public ConnectThread(LocalSocket socket){                this.socket = socket;        }        @Override        public void run(){            try {                input = socket.getInputStream();                byte[] buffer = new byte[1024];                int len = input.read(buffer);                 Log.d(TAG,"mBufferedReader:"+new String(buffer,0,len));                /* while((readString=mBufferedReader.readLine())!=null){                      //if(readString.equals("finish"))                     //  break;                      Log.d(TAG,"server recive :"+readString);                      break;                }  */                os = new PrintWriter(socket.getOutputStream());                  os.println("this is server\0");                  os.flush();                  os.close();                socket.close();                Log.d(TAG,"server send over");            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142

目录

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Android使用LocalSocket抓取数据
一步一步android(16):关于socket编程(2)【以非阻塞I/O服务器及Service为例】
java操作文件
Java如何使用JNI提取平台及硬件信息
socket1
#Scrcpy 源码分析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服