赞
踩
android下使用localsocket可以实现C与C,C与JAVA,JAVA与JAVA进程间通信。
localsocket是linux下的一种本地套接字,用来进行进程间通信,分为非命名和命名两种类型,非命名本地套接字只能用在父子进程之间通信(其实是只有保存了未命名的套接字的文件描述符的进程可以使用),命名套接字则没有这个限制。android在linux的本地套接字上进行封装。
android上使用localsocket主要是通过name来区分,也就是说客户端和服务端之间连接必须使用相同的name,并且一个name同一时间只能有一个服务端运行,name可以只一串字符串,如“com.penguin.sk”。
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;
}
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;
}
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();
}
}
}
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)
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 "$@"
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();
}
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。