Android provide LocalServerSocket and LocalSocket to create Unix domain sockets for local interprocess communication (IPC). Unix socket address can behave in three types[1],
- pathname
- unnamed
- abstract
LocalServerSocket provide two public constructors for create socket in Linux abstract namespace[2] and create socket using file descriptor that's already been created and bound[3].
Create LocalServerSocket using FileDescriptor
- Create socket and assign address(bind) -
native-lib.cpp
- Pass bound file descriptor to LocalServerSocket -
NativeClient.kt
- Accept new connections
import android.net.LocalSocket
import android.net.LocalSocketAddress
import java.io.*
// ...
fun createClient(pathname: String) {
val localSocketAddress = LocalSocketAddress(pathname, LocalSocketAddress.Namespace.FILESYSTEM)
val client = LocalSocket()
client.connect(localSocketAddress)
client.receiveBufferSize = 1024
client.soTimeout = 3000
var stream = FileInputStream(client.fileDescriptor)
val inputReader = InputStreamReader(stream)
val bufferReader = BufferedReader(inputReader)
// Read buffer
// ...
}
#include <sys/socket.h>
#include <sys/un.h>
#include <string>
#include <stdio.h>
// ...
char *socket_path;
struct sockaddr_un addr;
int fd;
socket_path = argv[0]; // Get socket path from arguments
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket error");
exit(-1);
}
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
perror("connect error");
exit(-1);
}
// Read or write on socket
const pathToSock = argv[1]; // Get socket path from arguments
const net = require('net');
const client = net.createConnection(pathToSock, () => {
console.log('connected to server!');
});
client.on('data', (data) => {
// ...
});
client.on('end', () => {
console.log('disconnected from server\n');
});