muduoライブラリ学習の設計と実装11-コネクタ(アクティブに接続を開始)

東陽の研究ノート

接続を能動的に開始することは、接続を受動的に受け入れることよりも複雑です。

  • 一方では、エラー処理は面倒です。
  • もう1つの側面は、再試行を検討することです。

ノンブロッキングネットワークプログラミングでは、接続を開始する基本的な方法は、connect(2)を呼び出すことです。ソケットが書き込み可能になると、接続が確立されます。もちろん、これはあらゆる種類のメッセージエラーを処理し、それらをコネクタクラスとしてカプセル化する必要があります。インターフェイスは次のとおりです。

class Connector : boost::noncopyable
{
    
    
 public:
  typedef boost::function<void (int sockfd)> NewConnectionCallback;

  Connector(EventLoop* loop, const InetAddress& serverAddr);
  ~Connector();

  void setNewConnectionCallback(const NewConnectionCallback& cb)
  {
    
     newConnectionCallback_ = cb; }

  void start();  // can be called in any thread
  void restart();  // must be called in loop thread
  void stop();  // can be called in any thread

  const InetAddress& serverAddress() const {
    
     return serverAddr_; }

コネクタの実装における2つ、いくつかの困難

  1. ソケットは1回限りです。エラーが発生すると(たとえば、相手が接続を拒否した場合)、ソケットを回復することはできず、閉じて再起動することしかできません。オブジェクトのライフサイクル管理に注意を払う必要があります
  2. エラーコードはaccept(2)とは異なります。
    • EAGAINは実際のエラーです。つまり、ローカルのエフェメラルポートが一時的に使い果たされており、ソケットを閉じて、しばらくしてから再試行する必要があります。
    • 接続されている戻りコードはEINPROGRESSです。
    • また、ソケットが書き込み可能であっても、接続が正常に確立されたとは限らないため、getsockopt(...)を使用して再度確認する必要があります。
  3. 再試行間隔は徐々に延長する必要があります。たとえば、0.5、1秒、2秒、4秒、最大30秒、つまりバックオフです。これにより、オブジェクトの存続期間の管理が困難になります。runAfterタイミングを使用していて、タイマーが切れる前にコネクタが破棄された場合、どうすればよいですか。デストラクタでタイマーをキャンセルします。
  4. 自己結合

おすすめ

転載: blog.csdn.net/qq_22473333/article/details/113756638