1

ネットワークソケットをリッスンし、受信したパケットを別のデーモンにルーティングするゲートウェイサービスを作成しています。boost asio を使用する予定ですが、いくつか質問があります。実装を計画しているサーバーの設計は次のとおりです。

  1. ゲートウェイは、boost asio を使用して TCP 接続をリッスンします。

  2. ゲートウェイは、boost asio を使用して、デーモンからストリーミングされた Unix ドメイン接続もリッスンします。

  3. tcp 接続にパケットがあるときはいつでも、ゲートウェイはパケット内のプロトコル タグを調べ、サービスがリッスンする UNIX ドメイン接続にパケットを配置します。

  4. サービス接続にパケットがあるときはいつでも、ゲートウェイはクライアント タグを確認し、それぞれのクライアント接続を確立します。

ゲートウェイ内のすべての記述子は、NOBLOCKING のものになります。

ゲートウェイがサービス接続に書き込んでいるときに、サービス ソケットがいっぱいになると、EAGAIN または EWOULDBLOCK エラーが発生する可能性があります。バッファをキューに入れ、「サービス接続が書き込みの準備を整えるのを待つ」ことで、これに取り組む予定です。

select システム コールを使用すると、「サービス接続が書き込みの準備を整えるのを待っている」ということは、writefd リストに fd を追加し、それを select に渡すことになります。サービス接続の書き込み準備が整ったら、キューに入れられたバッファを接続に書き込み、select の writefdlist からサービス接続を削除します。

ブースト asio で同じことを行うにはどうすればよいですか? そのようなことは可能ですか?

4

3 に答える 3

1

boost::asio を使用すると、ノンブロッキング モードや EAGAIN EWOULDBLOCK などのリターン コードをいじる必要はありません。これは、より高レベルのフレームワークであるため、隠されています。

典型的なパターンは

  1. io_service オブジェクトを作成します
  2. io_service にバインドしてソケットを作成します
  3. ソケットで非同期イベント (async_connect、async_read、async_write など) を作成します。
  4. io_service::run または同様のメソッドでディスパッチを実行します。
  5. asio は、時間になるとハンドラーをトリガーします。

boost::asio ページでを確認してください。非同期エコーサーバーは、タスクのテクニックを説明できると思います。

于 2013-03-08T05:56:55.930 に答える
1

そのアプローチを採用したい場合は、 を使用してReactor-Style operationsboost::asio::null_buffersを有効にします。さらに、メンバー関数を介して Boost.Asio ソケットを非ブロックに設定します。このオプションは、同期ソケット操作をノンブロッキングに設定します。これは、Boost.Asio がネイティブ ソケットをノンブロッキングとして設定し、同期操作のブロッキングをエミュレートするため、ネイティブ ソケットをノンブロッキングとして設定することとは異なります。socket::non_blocking()

ただし、Proactor スタイルの操作がオプションである場合は、アプリケーションが下位レベルの詳細の一部を無視できるようにするため、それらの使用を検討してください。proactor スタイルの操作を使用する場合、Boost.Asio はアプリケーションに代わって I/O を実行し、EWOULDBLOCKEAGAIN、およびERROR_RETRYロジックを適切に処理します。たとえば、Boost.Asio で前述のエラーのいずれかが発生すると、I/O 操作が内部キューにプッシュされ、再試行が延期され、他の操作を試行できるようになります。

多くの場合、Proactor-Style 操作の代わりに Reactor-Style 操作を使用する必要がある 2 つの制約があります。

  • 別のライブラリは、I/O 操作自体を実行することを想定しています。
  • メモリの制限。Proactor を使用すると、バッファーの寿命は読み取りまたは書き込み操作の期間を超える必要があり、同時操作には独自のバッファーが必要になる場合があります。Reactor を使用すると、データを読み取る準備ができたときにバッファーの有効期間を開始し、データが使用されなくなったときに終了することができます。
于 2013-03-08T18:48:49.280 に答える
0

複数のスレッドが接続に使用される同じソケット オブジェクトに書き込む場合は、ミューテックス (Windows を使用している場合はクリティカル セクション) を使用してコードをシングル スレッドにする必要があります。

-「ゲートウェイがサービス接続に書き込んでいるときに、サービスソケットがいっぱいの場合、EAGAIN または EWOULDBLOCK エラーが発生する可能性があります」については、ASIO が内部的にそれを処理すると信じているので、心配する必要はありません。それ。

于 2013-03-08T13:49:26.383 に答える