WebRTC获取本机默认网卡的IP地址

  • 当我们创建一个socket并且不绑定一个特定网络设备的时候(bind),我们通过getsockname接口总是会返回一个INADDR_ANY地址
  • 当我们不指定一个网络设备的时,我们要send时系统会给我们指定一个默认的设备
  • 如何获取系统的默认设备的地址呢?通过connect一个DNS地址再通过getsockname获取就可以了,以下是WebRTC的实现,P2P就是这样拿到本机地址的。
// These addresses are used as the targets to find out the default local address
// on a multi-homed endpoint. They are actually DNS servers.
const char kPublicIPv4Host[] = "8.8.8.8";
const char kPublicIPv6Host[] = "2001:4860:4860::8888";
const int kPublicPort = 53;  // DNS port.

IPAddress BasicNetworkManager::QueryDefaultLocalAddress(int family) const {
  RTC_DCHECK(thread_ == Thread::Current());
  RTC_DCHECK(thread_->socketserver() != nullptr);
  RTC_DCHECK(family == AF_INET || family == AF_INET6);

  std::unique_ptr<AsyncSocket> socket(thread_->socketserver()->CreateAsyncSocket(family, SOCK_DGRAM));
  if (!socket) {
    LOG_ERR(LERROR) << "Socket creation failed";
    return IPAddress();
  }

  if (socket->Connect(SocketAddress(family == AF_INET ? kPublicIPv4Host : kPublicIPv6Host, kPublicPort)) < 0) {
    if (socket->GetError() != ENETUNREACH && socket->GetError() != EHOSTUNREACH) {
      // Ignore the expected case of "host/net unreachable" - which happens if the network is V4- or V6-only.
      LOG(LS_INFO) << "Connect failed with " << socket->GetError();
    }
    return IPAddress();
  }
  return socket->GetLocalAddress().ipaddr();
}

SocketAddress PhysicalSocket::GetLocalAddress() const {
  sockaddr_storage addr_storage = {0};
  socklen_t addrlen = sizeof(addr_storage);
  sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
  int result = ::getsockname(s_, addr, &addrlen);
  SocketAddress address;
  if (result >= 0) {
    SocketAddressFromSockAddrStorage(addr_storage, &address);
  } else {
    LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket=" << s_;
  }
  return address;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值