当前位置:   article > 正文

LocalSocket实现进程间通信_socket_local_server

socket_local_server

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 := factory
include $(BUILD_JAVA_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := clientSocketJava
LOCAL_SRC_FILES := clientSocket
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := optional
include $(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=/system
export CLASSPATH=$base/framework/factory.jar
exec 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

目录

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/245045
推荐阅读
相关标签
  

闽ICP备14008679号