2

Linux で動作するソケット サーバーを作成しましたが、これはおそらく Linux 固有のものではありません。

poll()クライアントの状態を確認するために使用します。私のクライアントは、リクエストを送信した後、アクティブ (ハーフ) クローズを行います。クライアントのハーフクローズのため、サーバーは常にPOLLHUPとを取得しています。POLLERRも表示POLLRDHUPされるので、実際には半分閉じており、接続の閉じ/リセットではないことがわかります。私の問題は、以前の投票で半減期があったことをすでに知っているにもかかわらず、常にこれらのイベントを取得することです。

これを無効にして、is イベントを受信しないようにするにはどうすればよいですか? 追加して を実行しようとしましread()shutdown(fd, SHUT_RD)が、役に立たないようです。pollすでに処理したイベントに目覚めたくありません。

4

2 に答える 2

3

半分近くになったら、readfds セットに fd を含めるのをやめます。半分閉じる以外に読むものは何もありません。この時点から、関心のある唯一のものは「書き込み可能な」イベントです。

于 2011-07-08T01:20:23.363 に答える
0

POLLHUPリターンフラグを無視するだけです。既存のコードが正しければ、必要なことが実行されます。

poll()(EJPの回答で概説されている)からハーフクローズを取得し続けるという事実は機能であり、バグではありません。ファイルの終わりとまったく同じようにハーフクローズを扱うことができます。これは、アプリケーションがソケット バッファ内の最後のバイトを破棄する代わりに読み取ることができるようにするためです (これは、TCP ハーフ クローズの正しいセマンティクスです)。

「通常の」ファイルの終わりに達すると、poll()常にファイル記述子を読み取り準備完了として選択します。ループ アラウンドは、ファイルの終わりが見られるまでデータpoll()に想定されます。条件を無視すると、プログラムは半分閉じた状況で同じコードを使用してまったく同じことを実行し、ソケット バッファーの最後のバイトを取得できます。read()close()POLLHUP

同様に、 を気にせずに制御フローを実装する必要がありますPOLLHUP。ファイル記述子を調整する必要がある場合(つまり、現在、バイトを入れる場所がない場合) は、その記述子をセットから削除して、カーネルが読み取り準備完了でバグを報告しないようにします。もう一度指示するまで(スロットリングを解除して)中断します。すべてのデータが既にソケット バッファにあるという事実 (ビットが示すもの) も、違いはありません。read()poll()POLLHUP

于 2013-09-10T16:00:33.230 に答える