UNIXドメインソケット

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索
ソケット (BSD) > UNIXドメインソケット

UNIXドメインソケット: UNIX domain socket)や IPCソケット とは、単一のオペレーティングシステム内で実行されるプロセス間でデータを交換するためのデータ通信の終点。名前付きパイプに類似した機能を備えながら、パイプはバイトストリームにしか使えないが、UNIXドメインソケットは、バイトストリームだけでなく、データグラムとしても利用できる。 UNIXドメインソケットを使用しているプロセスは、共通の親プロセスを共有する必要はない。 UNIXドメインソケット用のAPIは、インターネットソケットのものに類似しているが、通信のために基礎となるネットワークプロトコルは使用していない。 UNIXドメインソケットはPOSIXオペレーティングシステムの標準コンポーネントである。

UNIXドメインソケットは、アドレス・名前空間としてファイルシステムを使用している。これらは、ファイルシステム内のinodeとしてプロセスから参照される。これは、2つのプロセスが通信するために、同じソケットを開くことができる。しかし、コミュニケーションは、完全にオペレーティングシステムのカーネル内で発生する。

データを送ることに加えて、プロセスは、sendmsg() およびrecvmsg() システムコールを使用してUNIXドメインソケット接続を経由してファイル記述子を送信することができる。

利用方法[編集]

C言語[編集]

socket() で第1引数の domain に AF_UNIX を指定する。第2引数の type は SOCK_STREAM, SOCK_DGRAM どちらも利用可能。そして、クライアント側の場合、その後 connect() を呼ぶ。

Java[編集]

以下のライブラリなどで利用可能。

Android (Java)[編集]

android.net.LocalSocket クラスで利用可能。

Mono[編集]

Mono.Unix.UnixClient クラスで利用可能。

PHP[編集]

URL を unix:// もしくは udg:// で始めることで利用可能。

ソースコード例[編集]

サーバ[編集]

C99 でのサーバ側のソースコード例は以下の通り。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
 
int main(void)
{
    // サーバーソケット作成
    int sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock == -1)
    {
        perror("socket");
        return 1;
    }
 
    // struct sockaddr_un 作成
    struct sockaddr_un sa = {0};
    sa.sun_family = AF_UNIX;
    strcpy(sa.sun_path, "/tmp/unix-domain-socket");
 
    // 既に同一ファイルが存在していたら削除
    remove(sa.sun_path);
 
    // バインド
    if (bind(sock, (struct sockaddr*) &sa, sizeof(struct sockaddr_un)) == -1)
    {
        perror("bind");
        goto bail;
    }
 
    // リッスン
    if (listen(sock, 128) == -1)
    {
        perror("listen");
        goto bail;
    }
 
    while (1)
    {
        // クライアントの接続を待つ
        int fd = accept(sock, NULL, NULL);
        if (fd == -1)
        {
            perror("accept");
            goto bail;
        }
 
        // 受信
        char buffer[4096];
        int recv_size = read(fd, buffer, sizeof(buffer) - 1);
        if (recv_size == -1)
        {
            perror("read");
            close(fd);
            goto bail;
        }
 
        // 受信内容を表示
        buffer[recv_size] = '\0';
        printf("message: %s\n", buffer);
 
        // ソケットのクローズ
        if (close(fd) == -1)
        {
            perror("close");
            goto bail;
        }
    }
 
bail:
    // エラーが発生した場合の処理
    close(sock);
    return 1;
}

クライアント[編集]

C99 でのクライアント側のソースコード例は以下の通り。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
 
#define MESSAGE "Hello World!"
 
int main(void)
{
    // ソケット作成
    int sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock == -1)
    {
        perror("socket");
        return 1;
    }
 
    // struct sockaddr_un 作成
    struct sockaddr_un sa = {0};
    sa.sun_family = AF_UNIX;
    strcpy(sa.sun_path, "/tmp/unix-domain-socket");
 
    // 接続
    if (connect(sock, (struct sockaddr*) &sa, sizeof(struct sockaddr_un)) == -1)
    {
        perror("connect");
        goto bail;
    }
 
    // 送信
    if (write(sock, MESSAGE, strlen(MESSAGE)) == -1)
    {
        perror("write");
        goto bail;
    }
 
    // クローズ
    close(sock);
    return 0;
 
bail:
    // エラーが発生した場合の処理
    close(sock);
    return 1;
}

関連項目[編集]

外部リンク[編集]