socket in android

Server  -  JAVA

package com.jim.ndkdemo;

import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

class ServerSocketThread extends Thread
{
    public static String TAG = "zjm";
    private boolean keepRunning = true;
    private LocalServerSocket serverSocket;

    private void readMsg(LocalSocket interactClientSocket) {
        StringBuilder recvStrBuilder = new StringBuilder();
        InputStream inputStream = null;
        try
        {
            inputStream = interactClientSocket.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            char[] buf = new char[4096];
            int readBytes = -1;
            while ((readBytes = inputStreamReader.read(buf)) != -1) {
                String tempStr = new String(buf, 0, readBytes);
                recvStrBuilder.append(tempStr);
            }
            Log.d(TAG, "Receive MSG: " + recvStrBuilder.toString());
        } catch (IOException e) {
            e.printStackTrace();
            Log.d(TAG, "resolve data error !");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void run()
    {
        try {
            serverSocket = new LocalServerSocket("pym_local_socket");
        } catch (IOException e) {
            e.printStackTrace();
            keepRunning = false;
        }
        while(keepRunning)
        {
            Log.d(TAG, "wait for new client coming !");
            try {
                LocalSocket interactClientSocket = serverSocket.accept();
                //由于accept()在阻塞时,可能Activity已经finish掉了,所以再次检查keepRunning
                if (keepRunning) {
                    Log.d(TAG, "new client coming !");
                    readMsg(interactClientSocket);
                }
            } catch (IOException e) {
                e.printStackTrace();
                keepRunning = false;
            }
        }

        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

public class MainActivity extends AppCompatActivity {

    public static String TAG = "zjm";
    private ServerSocketThread socketThread;
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        socketThread = new ServerSocketThread();
        socketThread.setName("zjmserver");
        socketThread.start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());


    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

Client - C++

#include <jni.h>
#include <string>
#include <android/log.h>

#include <sys/socket.h>
#include <sys/un.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define ANDROID_SOCKET_NAMESPACE_ABSTRACT 0

#define NO_ERR 0
#define CREATE_ERR -1
#define CONNECT_ERR -2
#define LINUX_MAKE_ADDRUN_ERROR -3
#define CLOSE_ERR -5


#define LOG_TAG "zjm"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

/* 构造sockaddr_un */
int socket_make_sockaddr_un(const char *name, int namespaceId, struct sockaddr_un *p_addr, socklen_t *socklen)
{
    size_t namelen;

    memset(p_addr, 0x00, sizeof(*p_addr));
    namelen  = strlen(name);

    // Test with length +1 for the *initial* ''.
    if ((namelen + 1) > sizeof(p_addr->sun_path)) {
        return LINUX_MAKE_ADDRUN_ERROR;
    }
    p_addr->sun_path[0] = 0;
    memcpy(p_addr->sun_path + 1, name, namelen);

    p_addr->sun_family = AF_LOCAL;
    *socklen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;

    return NO_ERR;
}

/* 连接到相应的fileDescriptor上 */
int socket_local_client_connect(int fd, const char *name, int namespaceId, int type)
{
    struct sockaddr_un addr;
    socklen_t socklen;
    //size_t namelen;
    int ret;
    ret = socket_make_sockaddr_un(name, namespaceId, &addr, &socklen);
    if (ret < 0) {
        return ret;
    }

    if(connect(fd, (struct sockaddr *) &addr, socklen) < 0) {
        return CONNECT_ERR;
    }

    return fd;
}

/* 创建本地socket客户端 */
int socket_local_client(const char *name, int namespaceId, int type)
{
    int socketID;
    int ret;

    socketID = socket(AF_LOCAL, type, 0);
    if(socketID < 0) {
        return CREATE_ERR;
    }

    ret = socket_local_client_connect(socketID, name, namespaceId, type);
    if (ret < 0) {
        close(socketID);
        return ret;
    }

    return socketID;
}

int SendMsgBySocket() {
    int socketID;
    struct sockaddr_un serverAddr;
    char path[] = "pym_local_socket";
    int ret;

    socketID = socket_local_client(path, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
    if (socketID < 0) {
        return socketID;
    }
    //Send Msg
    char buf[] = "hello";
    ret = write(socketID, buf, strlen(buf));

    ret = close(socketID);
    if (ret < 0) {
        return CLOSE_ERR;
    }

    return NO_ERR;
}

extern "C"
JNIEXPORT jstring

JNICALL
Java_com_jim_ndkdemo_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";

    int pid = fork();
    if (pid == 0) {
        //sub process
        setpgid(0, 0);
        int ret = SendMsgBySocket();
        LOGI("ret = %d", ret);
    } else if (pid > 0) {
        //int ret = SendMsgBySocket();
        //LOGI("ret = %d", ret);
    } else {
        LOGI("pid < 0");
    }

    sleep(1);

    return env->NewStringUTF(hello.c_str());
}
原文地址:https://www.cnblogs.com/hushpa/p/8099824.html