ネットワークプログラミングを始めると必ずselect()関数を使うことになると言っても過言ではないだろう。
select関数を簡単に言うと,”多重化されたI/Oの同期をとる”関数と言える。しかしこれだけではなんだかよくわからない。もう少しわかりやすく言うと、”複数のハンドル(ソケット)の状態を一回の操作で調査する”とも言える。
ネットワークプログラミングではソケットを使ってパケットのやりとりを置こうが、パケットを受診する際にパケットが到着するまで、受信関数(readやrecvなど)の呼び出しを使うと停止してしまう。このことをブロッキング処理という。パケットを一つだけ受信する場合はそれでも良いのですが、複数同時に取り扱う場合はブロッキングが起こってしまうと都合が悪い。そこでselectのような一度に複数の箇所を調査できるノンブロッキング処理の関数を使って処理を行うのが望ましいと言える。
selectのプロトタイプ宣言は以下のようになる。
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
それぞれの要素について説明すると、
nfds: 記述子集合の中で調べる記述子の数
readfds: 入力できる状態かを調べる記述子集合
writefds: 出力できる状態かを調べる記述子集合
exceptfds: 例外処理がペンディング状態かを調べる記述子集合
timeout: タイムアウト
注意点としては第一引数のnfdsはselectを使うと変更されるのでループ内で使う場合は、設定し直す必要があるということである。