Android Daemon의 IPC (Inter-Process Communication)
Android에서 Daemon 프로세스와 애플리케이션 간의 통신을 위해 IPC(Inter-Process Communication) 기법이 필수적으로 사용됩니다. Android는 다양한 IPC 방식을 제공하며, 각 방식은 성능, 보안, 구현 난이도에 따라 적절한 사용처가 다릅니다. 본 포스팅에서는 Android에서 사용 가능한 IPC 방식과, Daemon과 애플리케이션 간의 통신을 위한 Local Socket을 활용하는 방법을 설명합니다.
Android에서 사용 가능한 IPC 방식
Android는 기본적으로 여러 가지 IPC 기법을 제공합니다. 대표적인 방식은 다음과 같습니다.
1. Binder
Binder는 Android의 핵심 IPC 메커니즘으로, Android 프레임워크의 주요 서비스들이 Binder를 기반으로 동작합니다. Binder는 커널 레벨에서 동작하며, 안정성과 보안성이 뛰어난 반면, 구현이 비교적 복잡합니다.
특징:
- 높은 보안성 (SELinux 정책 적용 가능)
- 성능이 우수하며, 커널에서 직접 관리
- AIDL(Android Interface Definition Language)을 사용하여 인터페이스를 정의해야 함
- 구현이 다소 복잡하며, 클라이언트-서버 아키텍처 필요
2. Socket
Android에서는 Unix Domain Socket을 활용하여 프로세스 간 통신을 수행할 수 있습니다. 특히 Local Socket을 이용하면 네트워크를 사용하지 않고도 빠른 데이터 전송이 가능합니다.
특징:
- 네트워크 기반 IPC 방식과 유사하지만, Android 내에서 네트워크 없이 사용 가능
- 구현이 비교적 간단하며, 일반적인 TCP/UDP 소켓 프로그래밍과 유사
- 서버-클라이언트 모델을 적용 가능
- 바이너리 데이터 전송이 가능하여 성능이 뛰어남
3. Message Queue
Android에서는 System V 메시지 큐 또는 POSIX 메시지 큐를 사용할 수 있습니다. 이는 프로세스 간 데이터를 큐 형태로 전송하는 방식으로, 순차적인 데이터 처리에 유용합니다.
특징:
- 프로세스 간 메시지를 FIFO(First-In-First-Out) 방식으로 관리
- 특정 크기의 메시지 버퍼를 사용하여 데이터 전달
- 비교적 구현이 간단하지만, 고성능이 필요한 경우에는 적합하지 않음
이 외에도 Shared Memory(공유 메모리)나 Content Provider 등의 IPC 방식이 존재하지만, Daemon과의 통신에는 주로 Socket이나 Binder가 많이 활용됩니다.
Daemon과 앱 간의 통신을 위한 Local Socket 구현
Daemon과 Android 애플리케이션 간의 통신을 위해 Local Socket을 사용하는 방법을 설명합니다. Local Socket은 네트워크 소켓과 유사하지만, 네트워크를 거치지 않고 직접 프로세스 간 데이터를 주고받을 수 있습니다.
1. Daemon (서버) 코드 구현
NDK를 사용하여 Daemon을 C++로 구현하고, Local Socket을 사용하여 클라이언트(앱)와 통신할 수 있도록 설정합니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#define SOCKET_PATH "//data/local/tmp/my_daemon_socket"
#define BUFFER_SIZE 256
int main() {
int server_fd, client_fd;
struct sockaddr_un server_addr;
char buffer[BUFFER_SIZE];
// 소켓 생성
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (server_fd < 0) {
perror("Socket creation failed");
return 1;
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strcpy(server_addr.sun_path, SOCKET_PATH);
unlink(SOCKET_PATH);
// 소켓 바인딩
if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
return 1;
}
// 클라이언트 요청 대기
if (listen(server_fd, 5) < 0) {
perror("Listen failed");
return 1;
}
printf("Daemon listening on %s\n", SOCKET_PATH);
while (1) {
client_fd = accept(server_fd, NULL, NULL);
if (client_fd < 0) {
perror("Accept failed");
continue;
}
memset(buffer, 0, BUFFER_SIZE);
read(client_fd, buffer, BUFFER_SIZE);
printf("Received: %s\n", buffer);
write(client_fd, "Message received", 16);
close(client_fd);
}
close(server_fd);
return 0;
}
2. 클라이언트 (앱) 코드 구현
Android 애플리케이션에서 Daemon에 메시지를 보내는 클라이언트 코드를 작성합니다.
import java.io.*;
import java.net.*;
public class DaemonClient {
private static final String SOCKET_PATH = "//data/local/tmp/my_daemon_socket";
public static void main(String[] args) {
try {
// Local Socket 생성
Socket socket = new Socket();
socket.connect(new UnixDomainSocketAddress(SOCKET_PATH));
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
// 메시지 전송
String message = "Hello Daemon!";
outputStream.write(message.getBytes());
outputStream.flush();
// 응답 수신
byte[] buffer = new byte[256];
int bytesRead = inputStream.read(buffer);
String response = new String(buffer, 0, bytesRead);
System.out.println("Response from daemon: " + response);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
결론
본 포스팅에서는 Android에서 Daemon과 애플리케이션 간의 통신을 위한 IPC 방식을 소개하고, Local Socket을 활용한 Daemon과 클라이언트의 구현 방법을 설명하였습니다. Local Socket을 사용하면 네트워크를 거치지 않고 빠르고 안정적인 IPC를 구현할 수 있습니다.
Binder를 이용한 IPC는 보다 강력한 보안성과 Android 시스템과의 밀접한 연계를 제공하지만, 구현이 다소 복잡할 수 있습니다. 반면, Local Socket을 활용하면 네이티브 C/C++ 환경에서 Daemon을 효율적으로 구축하고 관리할 수 있습니다. 이를 기반으로 보다 확장성 있는 Android 시스템을 개발할 수 있습니다.
'Android > Daemon' 카테고리의 다른 글
Android에서 Daemon의 보안 및 SELinux 정책 (0) | 2025.06.23 |
---|---|
Android NDK를 활용한 사용자 정의 Daemon 개발 (0) | 2025.06.22 |
Android Daemon과 Java/Kotlin 인터페이스 연결 (0) | 2025.06.19 |
Android에서 사용자 정의 Daemon 등록 및 실행 방법 (0) | 2025.06.18 |
Android Daemon을 위한 Android.mk 및 CMakeLists.txt 구성 (0) | 2025.06.17 |