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

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操作的流程是:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,991评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,769评论 18 399
  • 路旁的梧桐叶子上捧着雨水,滴下又不滴下。天上云无风而飘动,一时不知去哪里。魏朝的君子站在树下嚼着寒食散,一丝不挂,...
    一捧秋水阅读 167评论 0 0
  • 异地恋好艰难,我一直觉得,我经历了很多感情的曲折,我可以把我内心的所有理论付诸实践,但是我高估了自己,我还是在这条...
    树洞的秘密阅读 190评论 0 0
  • 每天像打仗一样
    昙花舞阅读 81评论 0 0