2012-03-13 7 views
4

を受け入れるには、それがブロックしwinsocketsを使用しているとき機能を受け入れるにタイムアウトを設定することは可能ですか? setsockoptを使ってrecvして関数を送ることができるのですか?Winsockのタイムアウト

そうはいかないようですが、私は確実にしたいと思います。

+1

http://stackoverflow.com/questions/4181784/how-to-set-socket-timeout-in-c-when-making-multiple-connections –

+0

の可能な複製@Adrianoいいえ、その質問はクライアント側についてです、* accept *関数はサーバー側でのみ使用されます。彼らは* accept *関数について話していません。 – Alecs

+0

は、Windowsで、あなたは(?何とか、スレッドポーリング?)自分でタイムアウトを管理する必要はありませ –

答えて

7

選択機能はタイムアウトとともに使用できます。 selectはノンブロッキングソケットで最も一般的に使用されますが、ブロッキングソケットを渡すことを妨げるものは何も読んでいません。 select関数がタイムアウトすると、accept timeoutと同じ動作になります。 MSDN

から

「パラメータreadfdsは、読みやすくするためにチェックされるソケットを識別します。ソケットは聞く状態に現在ある場合は、着信接続要求を受信した場合、それが読めるとしてマークされますこのようをブロックせずに完了することが保証されて受け入れること。他のソケットの場合は、データをキューに入れられた可読性手段はRECVへの呼び出し、WSARecv、のWSARecvFrom、またはのrecvfromをブロックしないことが保証されるように読み取るための利用可能です。」

これは、あなたが期待している動作を与える必要があります。

+0

いいえ、選択は、ソケットの振る舞いを変更したり、機能を受け入れていない、それはまだ同じまま - と任意のタイムアウトなしまだブロックを受け入れ、私はそれをチェックした。 – Alecs

+1

重要な点は、最初にacceptを呼び出すべきではないことです。最初にreadfdsをlistenソケットに入れてselectを呼び出し、selectが返ってきたら、ソケットが読み取り可能とマークされている場合はacceptを呼び出して成功します。着信接続要求がない場合、選択はタイムアウトになります。 – Jay

+0

ああ、はい、これは私が欲しかったように動作します、ありがとう!しかし、[ここ](http://tangentsoft.net/wskfaq/articles/io-strategies.html)それは選択を呼び出すことは避けなければならないと言われています、あなたはそれをコメントできますか? – Alecs

0

これは、タイムアウトのaferリスニングソケットを閉じるには、別のスレッドを手配するのはとても簡単です。自動リセットイベントを作成し、accept()が復帰するたびに通知します。 WaitForSingleObject()でイベントを待機する関数を、タイムアウト間隔のループ内に記述します。 WFSOがWAIT_OBJECT_0以外のものを返した場合は、待機中のソケットを閉じて終了します。 accept()ループを入力する直前に、関数を呼び出すスレッドを作成します。

別の可能性がでAcceptEx()を使用して、OVERLAPPED構造体のhEventとして渡されたイベントにWFSO()のタイムアウトを待つことです。タイムアウトが発生した場合は、CancelIo()を使用して、ネットワークIOシステムからキューに入れられたacceptEx()完了を削除します。