2012-02-23 20 views
1

誰かがよう)(selectを使用して私にいくつかのコードを示したときに、私は完全にそれを失った。だから、基本的にはソケットファイルを挿入し、バインドした後何FD_ZEROといくつかの理由のための明確な以前の内容で聞くと言ってソケットファイル記述

FD_ZERO(&readfds); 
FD_SET(socket,&readfds); 
FD_SET(0,&readfds); 
.......// bind() and listen(),regular stuff 
// Before select(),this guy cleared readfds to null and sort of start all over again 
FD_ZERO(&readfds);// Behold,this is exactly the line confusing myself 
FD_SET(socket,&readfds); 
// select will be called in the future within a infinite loop 

fdを設定すると、0の記述子(標準入力)が見えなくなりました。

誰もがこの全部を説明できますか?私はこれが正しいように感じることはありませんが、私は本当にそれを把握できません。たぶん、いくつかの特定をすべてやり直す設定fdを設定することは現実的なメカニズムである...

私はbind()listen()がmanner.Iのいくつかの並べ替えでは、FDのセットポイントを壊すのカップルを設定変更し、outputs.Consequentlyを調べることができると思いましたfdセットはまったく変更されませんでした。

UPDATE:

本当に私を混乱させるが第2 FD_ZERO(&readfds)です。 明らかに、最初のものは、バッファーの錆びたものを取り除くようなものです。各反復で、将来のためにfdsetをデフォルトにクリアする必要があります。私はちょうど2番目を理解していない。それは間違ったものであるか、どんな速度でも傷つけません。

+1

'select'はfdsetを変更しますが、' bind'と 'listen'はできません。ポインタも与えられません。しかし、自分自身に好意を持ち、 'poll'や' epoll'のような現代的なAPIを使い、fdsetについてもう一度心配しないでください。 –

+0

はクールだが、私はちょうどそれを得ることはできない – jasonkim

+1

'poll'を使う。モダンでポータブルで高速です。 'epoll'はベンチマーク自己喜びのためだけであり、それが優れているベンチマークは実際の使用ニーズ(' epoll'が実際に 'poll'よりはるかに遅い)に対応していません。 –

答えて

4

あなたの混乱がどこにあるかわかりませんが、ここで説明します。

fdsetは0からインデックスされたファイル記述子のビットマスクです(技術的にはがビットマスクであると考えていますが、その他の実装は... strange)。

のでfdsetのようなものかもしれ:

   Byte 0        Byte 1 
+---+---+---+---+---+---+---+---+ +---+---+----+----+----+----+----+----+ 
|fd0|fd1|fd2|fd3|fd4|fd5|fd6|fd7| |fd8|fd9|fd10|fd11|fd12|fd13|fd14|fd15| 
+---+---+---+---+---+---+---+---+ +---+---+----+----+----+----+----+----+ 

アイデアは、あなたがそれに興味があるなら、あなたが与えられたFD(ファイルディスクリプタ)のためのビットを設定することです。あなたがそれに興味がないなら、あなたはビットをクリアなままにします。

FD_ZEROはすべてのビットをクリアします。これは良い開始点です。次に、2つのFD_SET呼び出しは、fd0(標準入力)とfd<socket>のビットを設定します。その後

、どちらかのソケット上の標準入力またはアクションのアクションがあった場合fdsetが戻ってくることを使用して選択コール(アクションのタイプselectにfdsetを渡すときに使用したパラメータの位置に依存する。パッシングfdsetを読むと、ソケットを読むことができるか、標準入力(キーボードを使用しているなど)に何かが表示された場合に返ることを意味します。

これは、 "チャット"アプリケーションは、相手側のあなたまたはあなたの友人からの入力を待つためです。

fdsetのビットを再びゼロにして再設定するのは、select自体がそのアクションを検出したfd(またはfds)を示すようにセットを変更するためです。

例:ソケットを介して何かが入ってきて、標準入力から何も入力されなかった場合、fdsetはselectによって変更され、そのビットのみが設定されます。そうすれば、FD_ISSETを使用して、どのfdsを見るべきかを検出できます。あなたがコメントで示しているように見えるよう、2つのFD_ZERO()/FD_SET()配列の間(readfdsを使用して、または他の呼び出し)selectコールがない、場合


は、はい、最初は以来、不要であることが表示されます情報は2番目の情報で上書きされます。

完全なコードや建築デザインのドキュメントを見ることなく、-----それを伝えるのは難しいです。

+0

私が混乱しているのは、実際にコードがクリアされ、readfds自体が2回あるということです。 – jasonkim

+0

@ y26jin、それは 'select'が配列を変更するからです - それを拡張する答えを追加しました。 – paxdiablo

+0

つまり、何かを変更するselect()の前に2番目のものが呼び出されました。 – jasonkim

1

Select()は、複数のソケットを同時に受信しようとしているときに使用されます。あなたがソケット接続をaccept()するたびにソケット記述子が返され、これを使ってファイルを送受信します。

FD_SETを実行すると、ソケットディスクリプタをセットに追加します(読み書き可能な場合があります)。 FD_ZEROは、その特定のセットからすべてのエントリを消去します。

本質的に接続を受け入れるたびに、ソケット記述子をセットに追加できます(つまり、そのソケットを読み書きする場合)。

select()関数を呼び出すときは、使用するセットを指定します。 (例えば:readfds)とselect()は、すでにそのセット(readfds)に入っているすべてのソケットをポーリングします。

詳細はbeej's guide to network programingを参照してください。学ぶための非常に良いチュートリアルです。

0

select(2)は、引数fdのセットを変更するため、各繰り返しでそれらを再初期化することになっています。