UNIXドメインソケット(英: UNIX domain socket)は単一マシン上の高効率なプロセス間通信に用いられる機能・インタフェースの一種である。
プロセス間通信 (Inter-Process Communication: IPC) は一般的に名前付きパイプやBSDソケットを利用したTCP通信などで実現できる。UNIXドメインソケットはBSDソケットの一種であり、単一マシン上でのプロセス間通信を目的としている。ソケット通信がもつ双方性・プロセスfork不要といった特徴を備えつつ、単一マシン上の通信である(=インターネットを介さない)ことを生かした高効率な通信を可能にしている。
UNIXドメインソケットは、アドレス・名前空間としてファイルシステムを使用している。具体的には、ソケットをファイルシステム内のinodeとして作成し、そのパス名をソケットのアドレスとする。これにより、2つのプロセスが通信するために、同じソケットを開くことができる。しかし、コミュニケーションは、完全にオペレーティングシステムのカーネル内で発生する。データを送ることに加えて、プロセスは、sendmsg()
およびrecvmsg()
システムコールを使用してUNIXドメインソケット接続を経由してファイル記述子を送信することができる。
POSIXはBSDソケットとしてUNIXドメインソケットインタフェースを提供している。BSDソケットのAF_UNIX
protocol familyがUNIXドメインソケットに相当する。受け入れ可能なsocket typeはSOCK_STREAM
・SOCK_DGRAM
・SOCK_SEQPACKET
の3種類である。
Go言語(の実行環境)では、Microsoft Windows上でもUNIXドメインソケットを使ったプログラムを動かすことができる。
特殊なUNIXドメインソケットとして、socketpair()
を用いて作られるものがある。socketpair()
はUNIXドメインソケットを2点作成し、一方のソケットに書き込んだデータがもう一方のソケットから読み出せる。パイプが一方通行の読み書きしかできないのに対し、socketpair()
にて作成したソケットでは双方向通信が可能である。
利用方法
C言語
socket()
関数における第1引数の domain に AF_UNIX
を指定する。第2引数の type は SOCK_STREAM
, SOCK_DGRAM
どちらも利用可能。そして、クライアント側の場合、その後 connect()
を呼ぶ。
Java
以下のライブラリなどで利用可能。
- junixsocket
- JUDS
また、JEP380によりJava 16よりjava.nio.channels.SocketChannel
で利用可能
Android
Android SDKに、Java/Kotlinから利用できる android.net.LocalSocket
クラスが実装されている。
Mono
Mono.Unix.UnixClient
クラスで利用可能。
PHP
URL を unix:// もしくは udg:// で始めることで利用可能。
ソースコード例
サーバ
C99 でのサーバ側のソースコード例は以下の通り。
クライアント
C99 でのクライアント側のソースコード例は以下の通り。
実装
Linux
LinuxカーネルにBSDソケット AF_UNIX
protocol familyとして実装されている。SOCKET(2)をはじめとするシステムコールをAPIとして公開している。
内部実装
LinuxにおけるUNIXドメインソケットは、バッファ(メモリ)への書き込みと読み込みという非常にシンプルな仕組みで実装されている。
Linuxカーネルのlinux/net/unix/af_unix.c
(GitHub mirror) に実装される。SOCK_STREAM
の場合、カーネル内部ではソケットバッファへのメッセージコピー・peerがもつsk_receive_queue
のtail、受信側のsk_data_ready
呼び出し、を繰り返すことでデータを転送する。
UNIXドメインソケットは単一マシン上のIPCが前提である。ゆえにTCPのようなプロトコルスイートは不要であり、プロトコルの重層が生むデータの入れ子構造を持たない。またネットワークに由来するパケットロスや到達順序保証の対応も必要ないため、バッファのread/writeというシンプルな仕組みで実装されている。結果として高効率なIPCが可能となっている。
制限事項
UNIXドメインソケットのアドレスとしてはそのパス名を用いるが、その最大長は概ね100バイト強に限られ、かつUNIXドメインソケットの実装に依存する。 これは、パス名一般の最大長よりも短い。この制限は、BSDによる初期の実装においてアドレスを格納する構造体struct sockaddr_un
をmbufを用いて確保しており、そのメモリサイズが128バイトに固定されていたことに起因している。その後、実装変更により他のOSへの移植を含め、ネットワークスタック内部での制限は解消されたが、互換性のためにAPI上のアドレス最大長制限は残されている。
脚注
関連項目
- ソケット (BSD)
外部リンク
- 仕様
- UNIX(7) Linux Programmer's Manual
socketpair
– The Open Group基本仕様書第7号2018年版「システムインターフェース」sendmsg
– The Open Group基本仕様書第7号2018年版「システムインターフェース」recvmsg
– The Open Group基本仕様書第7号2018年版「システムインターフェース」
cmsg(3)
– JM Project Linux Library Functions マニュアル- ucspi-unix, UNIXドメインソケット クライアントサーバー コマンドラインツール
- 解説
- Beej's Guide to Unix IPC - Unix Sockets
- Robert Watson (2005) "UNIXドメインソケット vs インターネットソケット"