socket

[戻る]

概要

プロセス間通信の方法の一つとしてsocketを使う。
通信を行う二つのプロセスのうち、一方をserver、もう一方をclientとする。
serverは通信を行うための口を用意する。

通信の準備

通信を行う口は以下の手順で用意する。これはserverが行う。

これで通信を行う口は用意された。この後、clientは自分で作ったsocketをこの口に結合(connect)し、serverはそれを受け入れる(accept)。serverのsocketに名前を付けるのは、clientがその名前のsocketに結合するのに識別名が必要だからである。
connectとacceptはどちらが先に発行されてもかまわない。お互い結合されるのを待つ。

socketの名前

socketを作るとき、定義域としてAF_UNIXAF_INETを指定する。それぞれ、UNIXドメインINETドメインと呼ばれる。
名前を付けるときはそのドメインの中で一意でなければならない。
UNIXドメインは、ひとつの計算機がその範囲である。この中で一意であると保証するのに簡単な方法としてファイルがある。そこで、名前を作るとその名前のファイルが作られる。こうすれば、そのシステムで一意であることが保証される。ただし、作られたファイルは残ってしまう。通信が終了しても自動的に消してはくれない。
INETドメインでは、ネットワークで結合されたすべてがその範囲である。この中で一意に名前を定めるのは容易ではない。そこで、まず計算機にネットワークで一意な名前を付け、それと組合せて名前を付ける。具体的には、計算機に付けられる名前はIPアドレスである、組み合わされるのはポート番号である。つまり、IPアドレス+ポート番号でINETdドメインで一意な名前を付ける。

通信

お互い結合してしまえば、後は通信するだけである。
送信はsend/writeで、受信はrecv/readで行う。socketを作るとファイルディスクリプタが与えられるので、低レベルのファイルアクセスと大体同じことができるので、read/writeも使える。通信と言ってもそんなに特殊なことをするわけではない。
送信は送りつけるだけだが、受信は相手から何か送られてくるのを待つので、間違えるとデッドロックしてしまう。ただし、結合そのものが切れてしまうと、recv/readで待っていた場合受信データ長0で抜けてきてくれる。

通信の終了

プロセスそのものを終わらせてしまってもいいのだが、一応終了の手順は以下の通りである。

UNIXドメインの場合、付けた名前のファイルが残るので、これを消しておく(unlink)。

プログラム例

以下のプログラム例は、serverがclientからのメッセージを受信して表示するものである。

複数のclientと通信するserver

ここまでは基本ということで1対1の通信の話をしてきたが、serverと呼ばれるものであれば複数のclientを通信する場合もある。こういう場合、selectを使うとよい。
これは、待ちたいフィルディスクリプタのリストを渡して、どれか来たら抜けて来てくれる。時間を指定すればその時間を過ぎれば何も来ていなくても抜けて来てくれる。
以下のプログラム例は、これを使って、複数のclientからの要求を処理するserverと、1秒毎にメッセージを送るclientである。UNIXドメイン版のみだが、もちろんINETドメインでも動作する。また、無限ループするプログラムなので、signalで終了を検知した場合終了処理をするようにしてある。

実際に使って気付いたこと

実際使ってみて気付いたことを以下に記すが、いろいろな環境で試したわけではないので、もしかしたら大丈夫かもしれない。


Copyright © 1998 by Jun Takahashi