ソケットは、2 つのプロセス間のポイントツーポイントの双方向通信を提供します。ソケットは、非常に多くの目的に使用でき、プロセス間およびシステム間通信の基本構成要素です。ソケットは、名前を結合できる通信の終端です。ソケットは、1 つの型と 1 つ以上の関連プロセスを持ちます。
ソケットは通信ドメインに存在します。ソケットドメインは、アドレッシング構造と一連のプロトコルを提供する抽象的なものです。ソケットは、同じドメイン内のソケットとだけ接続します。23 個のソケットドメインが識別されていて (<sys/socket.h> を参照)、Solaris 8 およびその互換オペレーティング環境では通常は UNIX ドメインとインターネットドメインだけが使用されます。
ソケットは、IPC の他の形態と同様に、1 つのシステム上のプロセス間の通信に使用できます。UNIX ドメイン (AF_UNIX) は、1 つのシステム上のソケットアドレス空間を提供します。UNIX ドメインのソケットは、UNIX パスで名前を指定されます。
ソケットは、異なるシステムにあるプロセス間の通信に使用することもできます。接続されているシステム間のソケットアドレス空間をインターネットドメイン (AF_INET) と言います。インターネットドメイン通信は、TCP/IP インターネットプロトコルを使用します。
ソケットのタイプは、アプリケーションに見える通信属性を定義します。プロセスは、同じタイプのソケット間だけで通信します。ソケットには次のタイプがあります。
ストリームソケットは、レコード境界のない双方向の逐次で信頼でき重複しないデータフローを提供します。ストリームは、電話の会話とほとんど同じように働きます。ソケットタイプは SOCK_STREAM であり、インターネットドメインでは伝送制御プロトコル (TCP) を使用します。
データグラムソケットは、双方向のメッセージフローをサポートします。データグラムソケットは、メッセージが送られた順序とは異なる順番でメッセージを受け取ることができます。データの中のレコード境界は保たれます。データグラムソケットは、郵便でやりとりする手紙の受け渡しとほとんど同じように働きます。ソケットタイプは SOCK_DGRAM であり、インターネットドメインではユーザデータグラムプロトコル (UDP) を使用します。
逐次パケットソケットは、固定した最大長のデータグラムに双方向で逐次的な信頼できる接続を提供します。ソケットタイプは、SOCK_SEQPACKET です。このタイプのプロトコルは、プロトコルファミリとしては実装されていません。
ローソケットは、基礎となる通信プロトコルへのアクセスを提供します。このソケットは、通常はデータグラムが中心ですが、その正確な特性はプロトコルが提供するインタフェースによって異なります。
socket(3SOCKET) を呼び出して、指定したドメインに指定したタイプのソケットを作成します。プロトコルを指定しないと、システムは指定されたソケットタイプをサポートしているプロトコルをデフォルトとして使用します。ソケットハンドル (記述子) が戻されます。
リモートプロセスは、アドレスが結合されるまでソケットを識別する方法を持ちません。通信するプロセスは、アドレスによって接続します。UNIX ドメインでは、接続は通常は 1 つまたは 2 つのパス名から構成されます。インターネットドメインでは、接続はローカルアドレス、リモートアドレス、ローカルポート、リモートポートから構成されます。ほとんどのドメインでは、接続は一意でなければなりません。
bind(3SOCKET) を呼び出して、パスまたはインターネットアドレスをソケットに結合します。bind(3SOCKET) を呼び出すには、ソケットのドメインに応じて、3 つの異なる方法があります。パスが 14 文字以下の UNIX ドメインソケットでは、次のようにします。
#include <sys/socket.h> ... bind (sd, (struct sockaddr *) &addr, length); |
UNIX ドメインソケットのパスが 14 文字よりも多くの文字を必要とする場合は、次のようにします。
#include <sys/un.h> ... bind (sd, (struct sockaddr *) &addr, length); |
インターネットドメインソケットでは、次のようにします。
#include <netinet/in.h> ... bind (sd, (struct sockaddr *) &addr, length); |
UNIX ドメインで名前を結合すると、名前付きソケットがファイルシステムに作成されます。ソケットを削除するには、unlink(2) または rm(1) を使用します。
ソケットの接続は、通常は対称的ではありません。1 つのプロセスが通常はサーバとして動作し、もう 1 つのプロセスはクライアントとして動作します。サーバは、以前に合意しているパスまたはアドレスにソケットを結合します。その後、ソケットでブロッキングします。SOCK_STREAM ソケットでは、サーバは listen(3SOCKET) を呼び出し、待ち行列に並べられる接続要求の個数を指定します。
クライアントは connect(3SOCKET) を呼び出して、サーバのソケットへの接続を開始します。UNIX ドメインの呼び出しは、次のようになります。
struct sockaddr_un server; ... connect (sd, (struct sockaddr_un *)&server, length); |
インターネットドメインの呼び出しは、次のようになります。
struct sockaddr_in; ... connect (sd, (struct sockaddr_in *)&server, length); |
クライアントのソケットが接続呼び出しの時点で結合されていないと、自動的に名前が選択されてソケットに結合されます。
SOCK_STREAM ソケットでは、サーバは accept(3SOCKET) を呼び出して接続を完了します。accept(3SOCKET) は、特定の接続だけに有効である新しいソケット記述子を戻します。サーバは、一度に複数の SOCK_STREAM 接続をアクティブにできます。
SOCK_STREAM ソケットとの間でデータを送受信する関数には、write(2)、read(2)、send(3SOCKET)、および recv(3SOCKET) があります。send(3SOCKET) と recv(3SOCKET) は、read(2) と write(2) によく似ていますが、いくつかの動作フラグが追加されています。
SOCK_STREAM ソケットは、close(2) の呼び出しによって破棄されます。
データグラムソケットは、接続の確立を必要としません。各メッセージが受信先アドレスを運びます。特定のローカルアドレスが必要な場合は、bind(3SOCKET) の呼び出しをデータ転送の前に常に実行しなければなりません。データは、sendto(3SOCKET) または sendmsg(3SOCKET) (send(3SOCKET) のマニュアルページを参照) の呼び出しによって送られます。sendto(3SOCKET) の呼び出しは send(3SOCKET) の呼び出しと同様ですが、受信先アドレスも指定します。
データグラムソケットメッセージを受信するには、recvfrom(3SOCKET) または recvmsg(3SOCKET) (recv(3SOCKET) のマニュアルページを参照) を呼び出します。recv(3SOCKET) では着信データ用に 1 つのバッファが必要ですが、recvfrom(3SOCKET) では着信メッセージ用と発信元アドレスを受け取るため用に 2 つのバッファが必要です。
データグラムソケットは、connect(3SOCKET) を使用しても、ソケットを指定された受信先ソケットに接続できます。接続するときは、send(3SOCKET) と recv(3SOCKET) を使用してデータを送受信します。
accept(3SOCKET) と listen(3SOCKET) は、データグラムソケットでは使用しません。
ソケットは、getsockopt(3SOCKET) でフェッチして setsockopt(3SOCKET) で設定できるいくつかのオプションを持っています。これらの関数は、固有のソケットレベル (level = SOL_SOCKET) で使用できますが、ソケットオプション名を指定しなければなりません。その他のレベルでオプションを操作するには、オプションを制御するプロトコルの番号を指定しなければなりません (詳細は、getprotoent(3SOCKET) についての記述を参照してください)。