問題タブ [select-syscall]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
linux - Linux でブロック (O_NONBLOCK なし) ファイル記述子を選択/ポーリングするのは適切ですか?
バグ
Linux では、select() がソケット ファイル記述子を「読み取り準備完了」と報告する場合がありますが、その後の読み取りはブロックされます。これは、たとえば、データが到着したが、検査時に間違ったチェックサムがあり、破棄された場合に発生する可能性があります。ファイル記述子が誤って準備完了と報告される状況が他にもある可能性があります。したがって、
ブロックしてはならないソケットでは O_NONBLOCK を使用する方が安全かもしれません。
しかしnetcat
、、、(しかし、ではありませんsocat
)O_NONBLOCKなしでFDを選択またはポーリングするように設定しています。wget
curl
これについてアプリをテストするための特別なライブラリを実装しましたが、失敗しています...
wget
/* 古くなったソケットからハングアップしread
、本来のようにタイムアウトしないことに触発されました*/
これをバグとして報告する必要がありますか、それとも彼らはそれを正しく行っていますか?
考えられる答え:
- "いいえ、poll/select で FD をブロックする => バグ";
- 「AF_INET[6] ソケットのみが選択時に誤作動する可能性があるため、ブロックしているネットワーク ソケットが poll/select にある場合にのみバグが発生します」;
- 「はい、これが原因で実際に障害が発生した場合にのみバグを報告してください」(wgetのように)。
c - Linuxでselectが使用されるのはなぜですか
私はシリアルプログラムを実行していましたが、使用するselect()
前にそれらが使用されていることを確認しましread()
た。なぜこれが必要なのですか。直接電話read()
して失敗するかどうかを確認できないのはなぜですか?また、ファイル記述子を1ずつインクリメントして、すでにに設定されているファイル記述子を渡すときに渡す必要があるのはなぜselect()
ですか?
例:
r=select(fd+1, &fds, NULL, NULL, &timeout);
ここで、fdsはすでにfdの値を持っています
c - select を使用して、インターフェイスが処理できる速さで複数のインターフェイスにデータを送信できますか
私は経験豊富なネットワーク プログラマーであり、アドバイスが必要な状況に直面しています。
いくつかのデータをいくつかの発信インターフェイスに配布する必要があります (それぞれが各インターフェイスに対応する異なる TCP ソケット接続を介して)。ただし、重要な部分は、より良い帯域幅、つまりより高速に送信できるインターフェイスで、より多く/ほとんどのデータを送信できる必要があるということです。
私が持っていた意見は、この目的のために選択 API (UNIX と Windows の両方) を使用することでした。過去にselect、poll、さらにはepollを使用したことがあります。ただし、データが利用可能な場合は常に、複数のソケットから読み取るためのものでした。
ここでは、いくつかのインターフェイスに連続したパケットを順番に書き込み、それぞれの書き込み記述子を監視し (パラメーターを選択)、利用可能な方 (最初にパケットを送信できたことを意味します) を介して、より多くのパケットを送信し続けます。その記述子。
ここで私の意図を達成することはできますか?つまり、10Mbps リンクのインターフェイスと 1Mbps の別のインターフェイスがある場合、より高速なインターフェイスを介してほとんどのパケットを取得できることを願っています。
更新 1:この場合、選択の動作はどうなるのだろうと思っていました。つまり、読み取り記述子で選択を呼び出すと、データが利用可能な記述子が返されます。ただし、私のシナリオでは、ディスクリプタに書き込んでいて、select が最初に書き込みを終えたものを返すのを待っているとき、select は、パケット全体が書き込まれた場合にのみ戻ることを保証します。つまり、一度に 1200 バイトを書き込もうとしたとします。1200全体が返された場合にのみ返されますか、それとも永続的なエラーがありますか? select がどのように動作するかはわかりませんが、それを説明するドキュメントが見つかりませんでした。