歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

在Android系統使用socket在Java層和native之間數據通信

Android是基於Linux的系統,系統底層機制基本上是相同的,因為分本地代碼和java代碼,並且是java代碼通過jni調用本地代碼執行。

因為UDP報文發送是有局限的,局限就是當發送方的速度遠遠的超過接受方的時候,底層會大量的丟失數據,而且用UDP還會比較容易引起端口的阻塞,因此需要更加強大的類來實現類似的功能。LocalServerSocket和LocalSocket正是在這樣的情況下產生的,是以UNIX空間為緩沖區來進行數據的存儲的.

實例一:Native本地代碼作客戶端發送請求,Java端作服務器端創建socket,並監聽處理socket請求:

import android.net.LocalServerSocket;
import android.net.LocalSocket;


class SocketListener extends Thread {

        @Override
        public void run() {
            try {
                LocalServerSocket server = new LocalServerSocket("com.jenny.vnc.localsocket");
                while (true) {   
                    LocalSocket receiver = server.accept();
                    if (receiver != null) {
                        InputStream input = receiver.getInputStream();
                        int readed = input.read();
                                                           
                        ...........//handle   
                       
                    }

                }

 server.close();


            } catch (IOException e) {
                Log.e(getClass().getName(), e.getMessage());
            }
        }
    }
JNI 的Native端代碼做客戶端:
#include <sys/socket.h>
void send_remote_request(char *msg)
{
    int localsocket, len;
    struct sockaddr_un remote;

    if ((localsocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    exit(1);
    }

    char *name="com.jenny.vnc.localsocket";//與java上層相同哦

    remote.sun_path[0] = '\0';  /* abstract namespace */
    strcpy(remote.sun_path+1, name);
    remote.sun_family = AF_UNIX;
    int nameLen = strlen(name);
    len = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);

    if (connect(localsocket, (struct sockaddr *)&remote, len) == -1) {
    return;
    }
   
    if (send(localsocket, msg, strlen(msg),0) == -1) {
    return;
    }
   
    close(localsocket);
}


實例二、Java作客戶端發送請求,Native本地代碼作服務器端監聽處理socket請求:

Java層的主要代碼:

   1. LocalSocket so = null;
   2. LocalSocketAddress addr;
   3. so = new LocalSocket();
   4. addr = new LocalSocketAddress(SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED);
   5. so.connect(addr);

如果能正常connect到addr,那就可以像一般文件操作那樣進行io讀寫了。

native層的主要代碼:

   1. cli_fd = android_get_control_socket(SOCKET_NAME);
   2. retval = listen(cli_fd, backlog);
   3. cli_fd_cmd = accept(cli_fd, (sockaddr *)&peeraddr, &socklen);

如果能夠正常accept到java端的連接,那就可以用標准的io讀寫操作來讀寫數據了。

Copyright © Linux教程網 All Rights Reserved