2009-08-24 8 views
2

私のサーバー/クライアントは、着信TCPトラフィックを読み取るための新しいスレッド "readerThread()"を開始します。このスレッドはread()をブロックします。このreaderThread()を終了するにはどうしたらいいですか?CでTCP読み取りでスレッドブロックを終了する

1つの方法は、スレッドが終了するときにソケットを閉じる別のスレッドを開始して、読み取りが終了するようにすることです。それを行うよりクリーンな/良い方法があります。

答えて

1

ブロッキングread()コマンドを使用している場合は、ほとんどの場合、ソケットをシャットダウンしてクリーンアップするための制御スレッドが必要です。

通常は、1秒後にタイムアウトするselect()コールを使用して、読み込むデータがあるかどうかをテストし、各タイムアウトサイクルで別のスレッドによってシャットダウンステータスフラグが設定されているかどうかを確認します。

純粋なブロッキングを使用する場合は、推奨どおりにコントロールスレッドを使用してください。

+0

UNIXネットワークプログラミングでは、select()のようなタイムアウトがありますか? Cでそれを行う例がありますか# – Kazoom

+0

あるいは、非ブロッキングI/Oを使用して、関数呼び出しが戻るたびにステータスをチェックしてください。 –

+0

シンプルなプログラムなら、Matthewの提案は良い考えです。私は今のところC#での例はありません。しかし、ええ、select()のように。 C#で選択呼び出しがあってもいます。 。 。選択はUnixコマンドだけでなく、ウィンドウ内にもあります。 –

-1

それを行う別の方法は、あなたがそれをシャットダウンする際に、独自のアプリケーション内の別の場所からあなたのリスニングソケットに0バイトのパケットを送信することです。

私は、ソケットを閉じると、リスニングスレッドによって例外がスローされるため、別のスレッドからのコーケットを閉じるよりもややきれいなアプローチだとわかりました。

+0

TCPには0バイトのパケットはありません。リスニングソケットに何も送ることはできません。 – EJP

0

正確に何をしているのか多少困惑しています。.NETのSocketクラスのread()メソッドはありません。

私の推奨するのは、特定のポートでリッスンしているスレッドの代わりに、Socket.Selectのスレッドブロックを持つ2番目のソケットを作成することです。その2番目のソケットへの接続は、シャットダウン要求としてください(おそらく、適切な認証の後、たとえば、そのソケットを介してアプリケーションパスワードを送信することによって)。

3

質問に間違いがありました。ここにあなたがすべきことがあると思います。

  • あなたは親スレッドでソケットを作成した場合、とだけは入ってくるデータを読み取るための、新しいスレッドを使用し、その後、私は(Socket.Shutdownを呼び出すことを示唆している)。インクルードは、メソッドを受信この方法ではありません(0を返します。バイト読み込み)、スレッドのメソッドから終了することができます。シャットダウンは送信/受信を無効にしますが、送受信待ちのバッファにデータがある場合は、ソケットを閉じる前に送受信を確実に行います。受信時にソケットがブロックされている間にシャットダウンを呼び出すと、Receiveメソッドは0を返しますが、ソケットエラーコード= Shutdown(または10058)のソケット例外をスローします。だから、それを捕まえることができます。

  • あなたは新しいスレッドでソケット、およびその受け入れて新しい接続(Socket.Listen()とSocket.Accept)を作成した場合、あなたはあなたの親スレッドからそのソケットに接続して、0バイトを送ることができます。 Receiveメソッドが0バイトを返すと、新しいスレッドを終了できます。

  • あなたは新しいスレッドでソケットを作成している、それが唯一のクライアントが(他のソケットに接続します)することができます場合、これはまったく良い方法ではありません。クライアントソケットを閉じるときに0バイトを送信するようにサーバーを構成しない限り、スレッドを中止する必要があります(推奨されません)。この方法では、クライアントアプリケーションはソケットを閉じるためのサーバーに依存します。

関連する問題