2017-11-27 6 views
0

私はLinuxとWindowsのC言語で実装されているシンプルなソケットサーバを持っていて、それをきちんとシャットダウンできません。selectでサーバソケットを検出しています

ソケットを作成し、バインドしてから呼び出します。次に、selectを使用して新しい接続を検出し、現在接続されているクライアントソケットの読み取りアクティビティをループします。ソケットをクローズしているクライアントはうまくいきます。それがセレクトアップを呼び起こし、問題が発生しているビットがきれいにループをクローズしています。 Naiveは、別のスレッドから、またはシグナルやCtrl-Cに応答して、サーバーソケット(私がリッスンして受け入れているソケット)を閉じていましたが、これは選択を呼び起こすことに失敗しました。

自己パイプトリックを使用して、必要に応じて選択を待つことができます(FIFOを作成し、選択リストに読み込み終了を含め、シャットダウンしたいときに書き込みます)。コードの構造を考えれば非常に便利です。 サーバーソケットを閉じるときに私の選択が目を覚ますことが期待されるかどうか、これが期待された動作かどうかは疑問でした。これはWindows上でこのように動作します。

ありがとうございました。

+1

リスニングソケットがselect fdのread fdセットにありますか? – Pras

+0

グローバル変数を配置し、pthread_killを使ってselectスレッドに信号を送ることはできますか? –

答えて

1

競合状態になりやすいソケット/ファイルディスクリプタを別のスレッドからクローズするのは悪い考えです。

select呼び出しは信号によって中断されます。必要に応じて自己パイプトリックとクローズソケットを使用して、selectスレッドでSIGINTを検出できます。代わりにパイプを介して信号数を通信

あるいは、信号ハンドラは、ちょうどpselectスレッドがチェックするグローバルsigatomic_t変数を設定し、pselect信号によって中断ときことができます。この場合、SIGINTは、pselectが呼び出された場合を除き、常にブロックする必要があります。

+0

問題を引き起こしている実際の環境は、テストがメインスレッドで実行されている間に明らかに1つのスレッドでサーバーを実行しなければならないテスト環境であり、テストが終了するとサーバーを閉じる必要があります。私は、これをよりきれいに行うために、コードの構造にパイプをきれいに含める方法を試してみる必要があります。ありがとう。 –

+0

残念なことに、セルフ・パイプ・トリックはUNIX上でのみ機能し、Windowsではselectがソケットでのみ機能します。私は最もポータブルな解決策は、ポートを作成し、一時的なポート上でlocalhostにバインドし、それに接続し、そのようなものの制御ポートとして使用することだと思うので、fifoの代わりに自己パイプソケットを使用してください。しかし、重い感じ。 –

+0

@TomQuarendon: "*サーバーを終了したい*"ので、実装でサーバーをシャットダウンする機能はありません。 – alk

関連する問題