2016-08-13 20 views
0

私は、ブロッキングrecv()コールが含まれているスレッドを持って、このような何か:Windowsでblocking recv()を終了するには?

{ 
    while(1) 
    { 
     recv(socket, buffer, sizeof(buffer), 0); 
    }  
} 

は今、私が何をしたいのか、それがそのブロッキング状態を終了させるために、別のスレッドからrecv()機能を知らせるためです。

次のいずれか:

setsockopt()SO_RCVTIMEOで、読み取りタイムアウトを設定し
  1. 、そしていつでもそれが引き金私は、Unixでこれを行う方法について語っ別の質問(How to let a thread which blocks on recv() exit gracefully?)から以下の回答を読んだことがあります状態変数をチェックして、あなたが に読書を停止するよう指示したかどうかを確認してください。
  2. ソケットの読み取りを永久に止めたい場合は、入力のためにシャットダウンしてshutdown(sd, SHUT_RD)としてください。これにより、recv()は今から0に戻って を返します。
  3. ソケットを非ブロッキングモードに設定し、 の状態変数で上記の(1)と同じ戦略を採用して、読み込み時にタイムアウトを指定してselect()を使用します。ただし、ノンブロッキングモードでは、送信操作にかなりの複雑さがあるので、 は上記(1)または(2)を優先する必要があります。

あなたの疑似コードには、EOSとエラーチェックがありません。私はそれが 本当にそのように見えないことを願っています。

CPUが枯渇し、テストに基づいて2番目の解決策がWindowsでサポートされていないためです(私は正しいですか?)。だから、ブロッキングを終了する別の解決策がありますrecv()

+2

オプション3は、ほとんどの場合に使用され、最も移植性の高いものです。私はそれらの神秘的な "相当な合併症"が何であるか分かりません。それはかなり切れ、乾燥しています。 –

+0

'select'を使うときは、ソケットを非ブロックモードにする必要はありません。ちょうど短いタイムアウト(例えば200msec)で 'select'を使用してください。 'select'が返ってきたら、状態変数をチェックして、停止するはずなのかどうか確認してください。ソケットにデータがある場合にだけ 'recv'を呼び出します。 – user3386109

+0

ブロックしたくない場合は、ブロック機能を使用することはかなりナンセンスです。 – Olaf

答えて

4

ブロックrecv()終了した場合のみ:

  1. データが読み込まれます。

  2. 読み出しタイムアウト(SO_RCVTIMEO)。

  3. 接続が閉じられています。

これらのオプションのいずれでも実行可能でない場合は、あなたが読まれるのを待っているものがある知っているまでselect()WSAAsyncSelect()、またはWSAEventSelect()によって報告されたように、単純に、ブロックモードでrecv()を呼び出さないする必要があります。

そうでない場合は、再書き込みあなたのソケットロジックのいずれかに:

  1. 非ブロックモードでソケットを使用します。

  2. WSARecv()またはRIOReceive/Ex()とオーバーラップI/OまたはI/O完了ポートを使用してください。 I/O操作はCancelIo/Ex()で取り消すことができます。

+1

CancelSynchronousIo()は機能しませんか? –

+1

@HarryJohnston私は知らない。私はそれを試していない、それはソケットAPIで動作するかどうかは文書化されていません。 –

関連する問題