2011-06-20 10 views
4

私はC++ boost asioライブラリを使用しています。そこで、ソケット上の新しい接続を聞きます。接続を取得すると、リクエストを処理し、ループ内の別のソケットで新しい接続を待機します。新しい接続なしでブーストasio-acceptorのブロックを解除しますか?

while (true) 
{ 
    tcp::socket soc(this->blitzIOService); 
    this->blitzAcceptor.listen(); 
    boost::system::error_code ec; 
    this->blitzAcceptor.accept(soc,ec); 
    if (ec) 
    { 
     // Some error occured 
     cerr << "Error Value: " << ec.value() << endl; 
     cerr << "Error Message: " << ec.message() << endl; 
     soc.close(); 
     break; 
    } 
    else 
    { 
     this->HandleRequest(soc); 
     soc.shutdown(tcp::socket::shutdown_both); 
     soc.close(); 
    } 
} 

私の理解によれば、常にthis-> blitzAcceptor.accept(SOC、EC)でブロックする必要があります。新しい接続が行われるたびにthis-> HandleRequest(soc);で処理する必要があります。でブロックし、でブロックします。これはblitzAcceptor.accept(soc、ec)です。

しかし、私が見ることは初めてそれがthis-> blitzAcceptor.accept(SOC、EC)と新しい接続が、要求を処理します作ったが、代わりにブロックしている時にブロックすることである。このもう一度でblitzAcceptor.accept(soc、ec)と入力してください。this-> HandleRequest(soc);およびブロックsoc.receive();が内部にあります。

これはいつも起こるわけではありませんが、ほとんどの場合発生します。この動作の理由は何でしょうか。また、新しいリクエストが作成されるまで、これは常にblitzAcceptor.accept(soc、ec)でブロックされます。

答えて

3

の理由は何ですか?

この動作は、クライアントコードに完全に依存します。それが接続しているが、要求を送信していない場合、サーバーはデータを受信するとブロックします。

どのように私は、新しい要求が行われるまで、それは常にthis-> blitzAcceptor.accept(SOC、EC) で をブロックすることを保証することができますか?

できません。しかし、サーバーは、接続を受け入れた直後に開始するタイムアウトを開始できます。クライアントがその期間内に要求を送信しない場合は、ソケットを閉じます。これを行うには、同期メソッドではなく非同期メソッドの使用に切り替える必要があります。

+0

ありがとうございました。あなたの説明は "この動作は完全にクライアントコードに依存しますが、接続してもリクエストを送信しない場合、サーバーはデータを受信するとブロックされます。正しい。私はHttpサーバーを作成しており、ブラウザが新しい要求をしたときにのみ新しい接続を作成するという印象を受けました。ここで私はそれが新しい要求を送信することなく新しい接続を作成することに気づいた。現在のところ、私は要求を処理して接続を閉じます。このような理由から、最適化のように新しい接続を作成することもあります。 –

1

listen(2)とファイルディスクリプタaccept(2)の両方を使用していることをファイルディスクリプタのread(2)呼び出しでブロックしていないことを確認してください。ファイルディスクリプタ番号を印刷すると、すぐに問題を見つけることができると思います。

関連する問題