UNIXドメインソケット

提供: セキュリティ
移動: 案内検索
スポンサーリンク

UNIXドメインソケット (Unix Domain Socket)とは、ローカルなプロセス間通信用のソケットです。

読み方

UNIXドメインソケット
ゆにっくす どめいん そけっと
Unix Domain Socket
ゆにっくす どめいん そけっと

概要

UNIXドメインソケットは、単一のOS無いで実行されるプロセス間のデータ交換で利用されます。ssh-agentなどのプログラムで利用されます。

使い方

uds_client.c

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
 
#define UNIX_DOMAIN_SCOKET_PATH "/tmp/unix-domain-socket"
 
int
main(int argc, char const* argv[])
{
        int sock = socket(PF_LOCAL, SOCK_STREAM, 0);
        if (-1 == sock) {
                err(EXIT_FAILURE, "can not create socket");
        }
        struct sockaddr_un sa = { 0 };
        sa.sun_family = PF_LOCAL;
        strcpy(sa.sun_path, UNIX_DOMAIN_SCOKET_PATH);
        if (-1 == connect(sock, (struct sockaddr*)&sa,
                                sizeof(struct sockaddr_un))) {
                err(EXIT_FAILURE, "can not connect");
        }
        char msg[] = "Hello";
        if (-1 == write(sock, msg, strlen(msg))) {
                err(EXIT_FAILURE, "can not write");
        }
        close(sock);
        return 0;
}

uds_server.c

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <err.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
 
#define UNIX_DOMAIN_SCOKET_PATH "/tmp/unix-domain-socket"
 
void
rm_socket(void){
        int r = unlink(UNIX_DOMAIN_SCOKET_PATH);
        if (-1 == r) {
                warn ("can not rm %s", UNIX_DOMAIN_SCOKET_PATH);
        }
}
 
int
main(int argc, char const* argv[])
{
        rm_socket();
        int sock = socket(PF_LOCAL, SOCK_STREAM, 0);
        if (-1 == sock) {
                err(EXIT_FAILURE, "can not create socket");
        }
        int sockoptval = 1;
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sockoptval,
                        sizeof(int));
        struct sockaddr_un sa = { 0 };
        sa.sun_family = PF_LOCAL;
        strcpy(sa.sun_path, UNIX_DOMAIN_SCOKET_PATH);
 
        int size = 0;
 
        size = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path);
        if (-1 == bind(sock, (struct sockaddr*)&sa,
                                size
                                //sizeof(struct sockaddr_un)
                                        )) {
                err(EXIT_FAILURE, "can not connect");
        }
        if (-1 == listen(sock, 1024)){
                err(EXIT_FAILURE, "can not listen");
        }
 
        for ( ; ; ) {
                socklen_t len = 0;
                int fd = accept(sock, (struct sockaddr *) &sa, &len);
                if (fd == -1) {
                        if (errno == EINTR) {
                                continue;
                        }
                        err(EXIT_FAILURE, "can not accept");
                }
 
                {
                        char buf[512];
                        int r = read(fd, buf, sizeof(buf));
                        if (r == -1) {
                                err(EXIT_FAILURE, "can not read");
                        }
                        (void) write(STDOUT_FILENO, buf, r);
                        (void) write(STDOUT_FILENO, "\n", 1);
                }
                close(fd);
        }
        close(sock);
        return 0;
}

コンパイル

make uds_client uds_server

ターミナル1

./uds_server

ターミナル2

./uds_client

関連項目




スポンサーリンク