プログラミングインタフェース

付録 A UNIX ドメインソケット

UNIX ドメインのソケットは、UNIX パスで名前付けされます。たとえば、ソケット名には /tmp/foo などがあります。UNIX ドメインソケットは、単一ホスト上のプロセス間でだけ交信します。UNIX ドメイン上のソケットは、単一ホスト上のプロセス間の交信にしか使用できないため、ネットワークプロトコルの一部とは見なされません。

ソケットタイプには、ユーザーが認識できる通信プロパティーを定義します。インターネットドメインソケットを使用すると、TCP/IP トランスポートプロトコルにアクセスできます。インターネットドメインは、AF_INET という値で識別します。ソケットは、同じドメイン内にあるソケットとだけデータをやりとりします。

ソケットの作成

socket(3SOCKET) 呼び出しは、指定されたファミリに指定されたタイプのソケットを作成します。

s = socket(family, type, protocol);

プロトコルが指定されないと (値が 0)、システムは要求されたソケットタイプをサポートするプロトコルを選択します。ソケットハンドル (ファイル記述子) が返されます。

ファミリは、sys/socket.h に定義されている定数の 1 つで指定します。AF_suite という定数は、名前を解釈するときに使用するアドレス形式を指定します。

次のコードでは、マシン内部で使用されるデータグラムソケットを作成します。

s = socket(AF_UNIX, SOCK_DGRAM, 0);

通常 protocol 引数には 0 (デフォルトのプロトコル) を設定します。

ローカル名のバインド

ソケットは、その作成時には名前がありません。アドレスがソケットにバインドされるまで、リモートプロセスはソケットを参照できません。通信プロセスは、アドレスを介して接続されます。UNIX ファミリでは、接続は、通常 1 つまたは 2 つのパス名からなります。UNIX ファミリのソケットは、必ずしも名前にバインドされる必要はありません。バインドされると、local pathnameforeign pathname などの順序セットは重複して存在できません。パス名では、既存のファイルを参照できません。

bind(3SOCKET) 呼び出しを使用すると、プロセスはソケットのローカルアドレスを指定できます。これによって、local pathname 順序セットが作成され、一方、connect(3SOCKET) および accept(3SOCKET) はアドレスのリモート側を固定することによってソケットの関連付けを完了します。bind(3SOCKET) は次のように使用します。

bind (s, name, namelen);

s はソケットハンドルです。バインド名は、バイト文字列で、サポートするプロトコル (複数も可) がこれを解釈します。UNIX ファミリ名には、パス名とファミリが含まれます。例では、UNIX ファミリソケットに /tmp/foo という名前をバインドしています。

#include <sys/un.h>
 ...
struct sockaddr_un addr;
 ...
strcpy(addr.sun_path, "/tmp/foo");
addr.sun_family = AF_UNIX;
bind (s, (struct sockaddr *) &addr,
		strlen(addr.sun_path) + sizeof (addr.sun_family));

この例では、AF_UNIX ソケットアドレスの大きさを判断するときには NULL バイトがカウントされないので、strlen(3C) を使用しています。

addr.sun_path で参照されるファイル名は、システムファイルの名前空間でソケットとして作成されます。呼び出し側は、addr.sun_path が作成されるディレクトリに書き込み許可を持っている必要があります。このファイルは、不要になったときに呼び出し側が削除してください。AF_UNIX ソケットを削除するには、unlink(1M) を使用します。

コネクションの確立

通常、コネクションの確立は非対称に行われます。1 つのプロセスは、クライアントとして動作し、もう一方のプロセスはサーバーとして動作します。サーバーは、サービスに関連付けられた既知のアドレスにソケットをバインドし、コネクション要求のためにソケットをブロックします。これで、無関係のプロセスがサーバーに接続できます。クライアントは、サーバーのソケットへのコネクションを起動することでサーバーにサービスを要求します。クライアント側では、connect(3SOCKET) 呼び出しでコネクションを起動します。UNIX ファミリでは、これを次のように表現します。

struct sockaddr_un server;
		server.sun.family = AF_UNIX;
		 ...
		connect(s, (struct sockaddr *)&server, strlen(server.sun_path) 
         + sizeof (server.sun_family));

コネクションエラーについては、「コネクションエラー」を参照してください。「データ転送」では、データの転送方法が、「ソケットを閉じる」では、ソケットを閉じる方法が説明されています。