問題タブ [select-function]
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.
c - select() が着信データを検出しない
目的: N 個のノード (異なるマシンで実行されている) は、相互に TCP 接続を確立することによって相互に通信する必要があります。メッセージの送受信は、プロセスによって作成された 2 つのスレッドによって行われます。最初に、メイン プロセスはすべてのノードを相互に接続し、2 つのスレッドを作成して、スレッドがデータの送受信に使用できるファイル記述子のリストを与えます。以下の構造体は、メイン プロセスによって埋められ、スレッドに渡されます。
PS: socketFd は、接続が確立された方法 (ノードからの接続をリッスンするか、ノードに接続するか) に応じて、accept() または socket() によって受信されるソケット記述子です。
サイズ MAX_NUM_OF_NODES の SNodeInformation の配列が使用されます。
送信スレッドは nodeInformation を通過し、以下に示すように、それ自体を除くすべてのノードにメッセージ「Hello」を送信します。
以下に示すように、受信スレッドは nodeInformation を通過し、ファイル記述子セットを設定し、select を使用して着信データを待ちます。
期待される出力: P1 (最初に開始) と P2 を machine1 で実行し、もう 1 つを machine2 で実行する 2 つのプロセスだけで試しました。マシン内の両方のプロセスが最初に接続し、次にスレッドがメッセージ「Hello」を送受信して終了する必要があります。
観測された出力: P1 はメッセージを送信でき、P2 (受信スレッド) はメッセージ「Hello」を受信できます。しかし、P1 (受信スレッド) は P2 (送信スレッド) からメッセージを取得できません。アプリケーションコードは両方のマシンで同じですが、毎回、最初に開始されたプロセスは他のプロセスからメッセージを取得しません。ファイル記述子が設定されているかどうかを確認するために印刷を追加しましたが、P1 では表示されず、P2 でのみ表示されます。受信プロセスの送信は失敗せず、6 で返されます。ファイル記述子の最大値を確認しましたが、正しいです。
最初に P2 を開始し、次に P1 を開始すると、P1 が P2 からメッセージを受信し、P2 が P1 からのメッセージを無限に待機している間に存在することがわかります。
問題がソケット記述子の不適切な使用によるものなのか、それともスレッドによるものなのか、よくわかりません。
c - SIGCHLD によるスリープ
一部のハードウェア センサーを 1 分に 1 回ポーリングし、読み取り値をデータベースに追加する C プログラムがあります。読み取り値が (分単位 + オーバーヘッド時間ではなく) 分単位に近づくようにするために、プログラムは実際の作業を行う子を作成し、別の子を作成する前に 60 秒間スリープします。
私が抱えている問題は、子からの SIGCHLD がスリープ (60) を中断し、1 分ごとに 1 つではなく、無制限の子が作成されることです。
これは私がそれをやろうとしてきた方法です:
select() を使用して、次のことを行うことで目的を達成できるとも聞きました。
しかし、何らかの理由で、これは while ループの 1 回の繰り返しでしか機能しません。その後、プログラムはまったく待機せず、常に子を作成します。
では、sigchld によって中断されることなく、プログラムにこれを実行させるにはどうすればよいでしょうか?
c - プロキシ サーバーで select()
Cでプロキシサーバーを構築しており、機能を理解しようとしていselect()
ます。クライアントから接続が確立され、実際の Web サーバーに接続するために別の接続を確立できるように、Web アドレスが抽出されるようにコードを作成しました。ページはプロキシによって受信され、クライアントに返されます。
これにより複数のクライアント要求を処理できるようになることは理解select()
していますが、Web サーバーへの 2 番目の接続がどのように役立つか (または実装方法) がわかりません。私が理解していることから、Web サーバーからデータを受信してクライアントに返すための while ループはもう必要ありません。
Web サーバー接続用に 2 つ目のファイル記述子セットが必要ですか? 2 つ以上のクライアント要求を処理している場合、Web サーバーへの適切な接続でそれらがリンクされていることを確認するにはどうすればよいですか? とにかく、助けていただければ幸いです。私はネットワーキングのチュートリアルとオンラインの他のいくつかのチュートリアルを実行しましたが、数日経ってもまだこの問題に頭を悩ませていません.
c - FD_SETSIZEと計算値
サーバー/クライアントのセットアップでは、サーバーが少数の(現時点では4つ)異なるソケットでクライアントに接続しています。現時点では、計算されたset_sizeでselectを使用していますが、代わりにFD_SETSIZEを使用する価値がある前に、上限は何ですか?
以下は、ポイントを説明するためのいくつかのコード例です。最初にセットを作成します。
set_sizeの計算方法は次のとおりです。
そして使用法:
最近、2つの新しいソケットを追加する必要があり、将来さらに追加する必要があるかもしれません。計算されたset_sizeではなくFD_SETSIZEを使用するのはいつですか?
c++ - select() が常にタイムアウトするのはなぜですか? (ウィンドウズ)
select を使用して、ネットワーク上の別のホストからの確認応答を待ちますが、常に 0 を返します。同様の質問を持つ他のスレッドを見たことがありますが、それらの問題は常に、fd_set をリセットしていないか、またはselect() の最初のパラメーターに正しい値を渡していません。fd_setをリセットしているため、それが問題の原因であるとは考えられず、msdnによると、明らかに最初のパラメーターがWindowsで無視されます。
//下にelse ifステートメントがありますが、そこには行きません
何があっても、この時点では 0 が返されます。クライアントとサーバーがソケットを介して互いに情報を送信しているのを見たので、クライアント側で間違ったアドレスに送信しているとは思いません。select() が待機しているパケットを送信するためのクライアント側のコードは次のとおりです。
この問題を経験したのは私だけではありません。これに対処する方法を知っている人はいますか?
編集: 誰かが _sockAddr が入力されている場所を尋ねたので、ここに含めます: ClientThread クラスがインスタンス化されている場所があり、sockaddr_in が渡されていることがわかります。
Edit2: さらにデバッグすると、select ではなく recvfrom の呼び出しでメッセージが受信されるため、sendto の呼び出しが目的のターゲットに到達していることがわかりました。ただし、非ブロッキング呼び出しを使用できるようにする必要があります。
c - Cで複数のUDPパケットのタイムアウトを設定するには?
サーバーが固定ウィンドウ サイズの単一ポートを介してクライアントにパケットを送信し、クライアントが受信した各パケットに対して ack パケットを返す UDP サーバー/クライアント プログラムを作成しています。ここで、サーバーがパケットの損失状況を処理するようにします。いくつかのグーグルでは、ALARM
またはを使用する必要があるようSELECT
です。確かに、1 つのパケットを送信して、ack またはタイムアウトを待ってから別のパケットを送信することはしたくありませんがSELECT
、タイムアウト中に呼び出し関数をブロックするので、良くないと思います。ALARM
1 つのプログラムは 1 つしか持つことができないため、どちらも良くありませんALARM
。サーバーが送信する複数のパケットのタイムアウトを追跡できるようにする方法はありますか?
c - eventfd に相当する Windows はありますか?
私は、ソケットの動作をエミュレートするクロスプラットフォーム ライブラリを作成しており、その間に追加機能があります (App->mylib->sockets)。
プログラマーにとって可能な限り透過的にしたいので、 select や poll などのプリミティブは、この lib に応じて機能する必要があります。
問題は、データが実際のソケットで (たとえば) 利用可能になると、多くの処理を行う必要があるため、select が実際のソケット fd を指している場合、アプリは長時間ブロックされます。データが消費される準備ができた場合にのみ、選択/ポーリングのブロックを解除したい (私のライブラリがすべての処理を完了した後)。
だから私はこのeventfdに出くわしました。これにより、私がやりたいことを正確に行うことができます。
私は Linux 環境に精通しているため、windows での eventfd に相当するものは何なのかわかりません。検索しようとしましたが、運がありませんでした。
注: 別の方法として、インターフェイスに接続された別のソケットを使用することもできますが、これはオーバーヘッドが大きいようです。Windowsにこの機能がない(そう見える)という理由だけで、すべてのデータでシステムコールを行う。
または、車輪を再発明して、独自の選択を実装することもできます。=/
c - バッファにデータがあっても select() がタイムアウトする
このプログラムは (私が信じている) select() (ARM 用の Debian で) をそのまま適用したものです。XBEEDEVICE はシリアル ポートを指します。シリアル ポートが存在し、ic がデバイスに接続されています。
問題は、受信したデータがあっても select() が 0 を返すことです。最後の「else」を一時的にコメントアウトすると、プログラムは TIMEOUT を出力し、次にリモート デバイスから返された文字列を出力します。
c - ノンブロッキングconnect()とEINTR
UNIXネットワークプログラミングのStevensのconnect_nonb()を使用しています。
この関数を使用すると、connect()のカスタムタイムアウトが可能になります。接続が成功するのを待っているselect()でブロックしているときに、シグナルが受信された場合、select()は-1(EINTR)で終了します。この時点で、select()タイムアウトは期限切れになっておらず、接続は成功していません(つまり、ターゲットホストが切断されている可能性があります)が、後続のgetsockopt()はエラーを返しません。
Getsockopt()はエラーを返す必要がありますか、それともStevensコードはselect()の戻りコード(およびerrno)をチェックする必要がありますか?
現在、存在しないホストに接続し、シグナルがselect()に割り込むと、この関数は誤って成功を返します。
c - ブロッキング ソケットとノンブロッキング ソケットで select を使用した場合の影響
select() 呼び出しでブロッキング ソケットを使用するのではなく、select() 呼び出しで非ブロッキング ソケットを使用すると、プログラムの動作はどのように異なりますか?