2012-12-26 9 views
5

accept機能を使用してクライアントを受け入れるためのタイムアウトクロスプラットフォームソルーションは、ソケットを非ブロッキングに設定せずにありますか?タイムアウトでソケットを受け入れる方法

私はselectの機能を使うべきだと知っていますが、間違っているのは何ですか?

SOCKET NativesAcceptClient(SOCKET s, int timeout) 
{ 
    int iResult; 
    struct timeval tv; 
    fd_set rfds; 
    FD_ZERO(&rfds); 
    FD_SET(s, &rfds); 

    tv.tv_sec = (long)timeout; 
    tv.tv_usec = 0; 

    iResult = select(s, &rfds, (fd_set *) 0, (fd_set *) 0, &tv); 
    if(iResult > 0) 
    { 
     return accept(s, NULL, NULL); 
    } 
    else 
    { 
    //always here, even if i connect from another application 
    } 
    return 0; 
} 

これを修正するにはどうすればよいですか? ありがとう!

+0

@ryanbworkいいえ、タイムアウトは10です – Boris

+0

私の解決策を見ますか? – ryanbwork

+1

はすぐに選択から飛び出していますか、または飛び出す前に10秒待っていますか(接続していない場合)? (Windows以外のプラットフォームで言及されているs + 1を除いて)うまくいきます。 – mark

答えて

2

selectコールの最初のパラメータは、fd_setセットの最大番号のファイル記述子に1を加えたものに等しくなければなりません(here参照)。最初の引数をs+1に変更してみてください。あなたのセットに複数のソケットがあるときは、ロジックを追加する必要があります。

+0

ありがとう、しかし、私はWindows上で最初のパラメータが無視されることを知っているので、今Windowsでテストしています – Boris

+0

あなたの着信接続が10秒のウィンドウ内で行われていることを確認できますか? – ryanbwork

0

select()の最初の引数は、少なくとも1である大きいの任意のビットセット内のファイル記述子の最大値より大きいintです。この場合

iResult = select(s + 1, &rfds, (fd_set *) 0, (fd_set *) 0, &tv); 

が有効です。

1

select()ソケットが通知された場合は0を返し、タイムアウトの場合は0を返し、エラーの場合は-1を返します。 select()は実際にあなたに戻って何の価値がありますか?あなたは> 0と< = 0だけをチェックしています。つまり、-1と0を区別していないことを意味します。もし0を返していれば、クライアントはあなたのソケットに接続していませんが、-1を返していれば、最初から有効ではありません。

関連する問題