Re: select関数でパケット受信をチェックする時のFD_ZERO,FD_SET関数の必要性って?
KMochidaです。皆様、ご回答大変感謝致します。m(_ _)m
> そうなってないと、調べたくもないディスクリプタまで調べられてし
> まって使いにくいじゃないですか。
>> 『3番ディスクリプタのみに届いている場合は
>> という風に3番ディスクリプタにビットは立たないという事になるんですね。
> え、最初に1だったもののうち、実際にデータが到着したものは1のま
> ま残り、到着しなかったものは0になるんじゃないの。
> だから届いてるなら1は立つと思うけど。 久野
分かってきました。
とりあえず、実験的してみました。
各関数処理後のビットがどうなっているか逐一吐かせてみました。
FD_ZERO(&mask);
↓
mask.fds_bits[1]、mask.fds_bit[0]、の64ビット分を「0」にする。
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000
↓
FD_SET(0,&mask);
↓
mask.fds_bits[1]、mask.fds_bit[0]、の0ビット目を「1」にする。
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0001
↓
FD_SET(4,&mask);
↓
mask.fds_bits[1]、mask.fds_bit[0]、の4ビット目を「1」にする。
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
0001
↓
FD_SET(9,&mask);
(select関数での有効ビット幅外ではどうなるか観察する為に更に9ビット目を立てて
みる)
↓
mask.fds_bits[1]、mask.fds_bit[0]、の9ビット目を「1」にする。
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 0001
0001
↓
select(4+1,&mask,NULL,NULL,NULL);
↓
selectの返値は1であった
(0〜4番ディスクリプタの内、少なくともひとディスクリプタにバケットが到達した
と分かる)。
↓
mask.fds_bits[1]、mask.fds_bit[0]
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
0000
となりました
(有効ビット幅外である9番ディスクリプタも「0」にされちゃいました)。
、、、という事は
select(n+1,&mask,NULL,NULL,NULL);は
0番〜n番ディスクリプタでパケットが到達しているディスクリプタでしかも、予め
ビットが立っているディスクリプタを「1」にする(勿論、複数のディスクリプタがこ
の用件を満たしてれば複数のディスクリプタが1となる)。
そして、それ以外のディスクリプタ、つまり、
最初から「0」になっているディスクリプタ、パケットが到達していないディスクリ
プタ、有効ビット幅外のディスクリプタは全て「0」にしてしまう
のですね。
> かなり簡略されてて居ることがあるのですが、selectに関しては
> linuxのほうが分かりやすいかもしれません。BSDのほうは「ディスクリプタのア
> ドレス」という表現が出てきて分かりにくい)。
> ただ、頭から字を追って読んでもわけが分からないかも。
> selectは複数のファイルディスクリプタを並行に見張るシステム
> コールであるということを頭において読むと、理解できると思います。
> P.S.
> 「WEBにある解説記事よりmanページのほうがコンパクトで正確で
> わかりやすい」と思えるようになったら、もう初心者の気持ちが
> 分からなくなっている証拠だったりして。
有難うございます。
manの方は読んでて混乱してきて、ついイラストも載っている書籍やWEBの解説を読ん
でしまいます。
manで読めるようになりたいと思います。
> fd_set のビット数とmax user processesは関係ないので、ビット数を知りたけれ
ば
> システムヘッダファイルで、FD_SETSIZE の定義を探すのが良いかと思います。
> printf("%d\n",sizeof(fd_set)*8); でもいいですけど。
cygwinでは
$ ulimit -a | grep max
max user processes (-u) 63
で
printf("%d\n",sizeof(fd_set)*8);
を試すと「64」になりましたのですっかり勘違いしておりました。
因みに、RedHat9上では
$ uname -a
Linux hoge.foo.dydnd.net 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 i686 i686
i386 GNU/Linux
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7168
virtual memory (kbytes, -v) unlimited
となっていて、
printf("%d\n",sizeof(fd_set)*8);
を試すと「1024」となりました。でもfd_set のビット数はopen files数とも違うん
ですね。
飽くまで、FD_SETSIZEで定義されている値なのですね。
Fnews-brouse 1.9(20180406) -- by Mizuno, MWE <mwe@ccsf.jp>
GnuPG Key ID = ECC8A735
GnuPG Key fingerprint = 9BE6 B9E9 55A5 A499 CD51 946E 9BDC 7870 ECC8 A735