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讀寫操作來讀寫數據了。