美文网首页
穿透时4次握手的详细过程

穿透时4次握手的详细过程

作者: 古则 | 来源:发表于2017-05-27 15:55 被阅读115次

    1、调用逻辑

    首先看穿透之前的ping(stun bindingrequest)的调用流程

    穿透时的4次握手.jpg

    2、具体方法分析

    看图中OnCheckAndPing的代码

    void P2PTransportChannel::OnCheckAndPing() {
      // Make sure the states of the connections are up-to-date (since this affects
      // which ones are pingable).
      UpdateConnectionStates();
      // When the best connection is either not receiving or not writable,
      // switch to weak ping interval.
      int ping_interval = weak() ? weak_ping_interval_ : STRONG_PING_INTERVAL;
      if (rtc::Time64() >= last_ping_sent_ms_ + ping_interval) {
        Connection* conn = FindNextPingableConnection();
        if (conn) {
          PingConnection(conn);
          MarkConnectionPinged(conn);
        }
      }
      int delay = std::min(ping_interval, check_receiving_interval_);
      thread()->PostDelayed(delay, this, MSG_CHECK_AND_PING);
    }
    

    UpdateConnectionStates就是对connection的状态做出更新,这里先暂时不管。

    2.1,ping的频率的设定

    来看

    //p2ptransportchannel.cc 212L
    // for pinging.  When the socket is writable, we will use only 1 Kbps because
    // we don't want to degrade the quality on a modem.  These numbers should work
    // well on a 28.8K modem, which is the slowest connection on which the voice
    // quality is reasonable at all.
    static const int PING_PACKET_SIZE = 60 * 8;
    // STRONG_PING_INTERVAL (480ms) is applied when the best connection is both
    // writable and receiving.
    static const int STRONG_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 1000;
    // WEAK_PING_INTERVAL (48ms) is applied when the best connection is either not
    // writable or not receiving.
    const int WEAK_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 10000;
    
     // When the best connection is either not receiving or not writable,
      // switch to weak ping interval.
      int ping_interval = weak() ? weak_ping_interval_ : STRONG_PING_INTERVAL;
    

    上述方法的目的是确定ping的频率,在best_connection不可读,不可写的情况下,使用较快频率的ping,在best_connection可读,可写时使用较慢频率的ping。

    2.2、FindNextPingableConnection,寻找下一个需要ping的connection

    // Returns the next pingable connection to ping.  This will be the oldest
    // pingable connection unless we have a connected, writable connection that is
    // past the maximum acceptable ping interval. When reconnecting a TCP
    // connection, the best connection is disconnected, although still WRITABLE
    // while reconnecting. The newly created connection should be selected as the
    // ping target to become writable instead. See the big comment in
    // CompareConnections.
    Connection* P2PTransportChannel::FindNextPingableConnection() {
      int64_t now = rtc::Time64();
      Connection* conn_to_ping = nullptr;
      if (best_connection_ && best_connection_->connected() &&
          best_connection_->writable() &&
          (best_connection_->last_ping_sent() + config_.max_strong_interval <=
           now)) {
        conn_to_ping = best_connection_;
      } else {
        conn_to_ping = FindConnectionToPing(now);
      }
      return conn_to_ping;
    }
    

    对该方法的源码进行详细分析,可以得出webrtc选择一个connection来进行ping操作的流程是:

    相关文章

      网友评论

          本文标题:穿透时4次握手的详细过程

          本文链接:https://www.haomeiwen.com/subject/oysqfxtx.html