Chromium 网络栈之NetworkChangeNotifier
发布于 2021-11-15
NetworkChangeNotifier
NetworkChangeNotifier 是监控系统网络环境变化的类。
Observer
我们可以向它注册一些 observer,来获取相关的事件。
NetworkChangeNotifier 目前有以下几种 Observer:
- IPAddressObserver,通知 IP 地址发生了变化
- ConnectionTypeObserver,通知网络连接发生了变化
- DNSObserver,通知 DNS 配置发生了变化
- NetworkChangeObserver,通知网络发生了变化,功能跟上面的 Observer 有些重复
- MaxBandwidthObserver,通知网络最大带宽发生了变化
- NetworkObserver,通知网络的连接与断开
LoggingNetworkChangeObserver
LoggingNetworkChangeObserver 类就是继承实现了 NetworkChangeNotifier 里面的一些 Observer 接口,从而把网络变化相关的事件转发给 NetLog。
NetworkWatcher
我们也可以实现一个 NetworkWatcher 的类,看看能从 NetworkChangeNotifier 那里获取到哪些信息。
network_watcher.h 文件内容:
#ifndef NETWORK_WATCHER_H_
#define NETWORK_WATCHER_H_
#include "base/macros.h"
#include "net/base/network_change_notifier.h"
#include "net/dns/dns_config.h"
class NetworkWatcher
: public net::NetworkChangeNotifier::IPAddressObserver,
public net::NetworkChangeNotifier::ConnectionTypeObserver,
public net::NetworkChangeNotifier::DNSObserver,
public net::NetworkChangeNotifier::NetworkChangeObserver {
public:
NetworkWatcher();
~NetworkWatcher() override;
void Init();
void Shutdown();
private:
// IPAddressObserver
void OnIPAddressChanged() override;
// ConnectionTypeObserver
void OnConnectionTypeChanged(
net::NetworkChangeNotifier::ConnectionType type) override;
// DNSObserver
void OnDNSChanged() override;
void OnInitialDNSConfigRead() override;
// NetworkChangeObserver
void OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) override;
void PrintDnsConfig();
void PrintNetwork();
std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
DISALLOW_COPY_AND_ASSIGN(NetworkWatcher);
};
#endif // NETWORK_WATCHER_H_
----------------------------------------------------------------------
network_watcher.cc 文件内容:
#include "network_watcher.h"
#include "base/logging.h"
#include "net/base/network_interfaces.h"
NetworkWatcher::NetworkWatcher() {}
NetworkWatcher::~NetworkWatcher() {}
void NetworkWatcher::Init() {
network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
net::NetworkChangeNotifier::AddIPAddressObserver(this);
net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
net::NetworkChangeNotifier::AddDNSObserver(this);
net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
}
void NetworkWatcher::Shutdown() {
if (network_change_notifier_) {
net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
net::NetworkChangeNotifier::RemoveDNSObserver(this);
net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
}
network_change_notifier_.reset();
}
void NetworkWatcher::OnIPAddressChanged() {
LOG(WARNING) << "NetworkWatcher::OnIPAddressChanged";
PrintNetwork();
}
void NetworkWatcher::OnConnectionTypeChanged(
net::NetworkChangeNotifier::ConnectionType type) {
LOG(WARNING) << "NetworkWatcher::OnConnectionTypeChanged "
<< net::NetworkChangeNotifier::ConnectionTypeToString(type);
PrintNetwork();
}
void NetworkWatcher::OnDNSChanged() {
LOG(WARNING) << "NetworkWatcher::OnDNSChanged";
PrintDnsConfig();
}
void NetworkWatcher::OnInitialDNSConfigRead() {
LOG(WARNING) << "NetworkWatcher::OnInitialDNSConfigRead";
PrintDnsConfig();
}
void NetworkWatcher::OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) {
LOG(WARNING) << "NetworkWatcher::OnNetworkChanged "
<< net::NetworkChangeNotifier::ConnectionTypeToString(type);
PrintNetwork();
}
void NetworkWatcher::PrintDnsConfig() {
net::DnsConfig dns_config;
net::NetworkChangeNotifier::GetDnsConfig(&dns_config);
for (net::IPEndPoint nameserver : dns_config.nameservers) {
printf("nameserver %s\n", nameserver.ToString().c_str());
}
for (std::string s : dns_config.search) {
printf("search %s\n", s.c_str());
}
for (auto host : dns_config.hosts) {
printf("host:%s\t%s\n", host.first.first.c_str(),
host.second.ToString().c_str());
}
}
void NetworkWatcher::PrintNetwork() {
net::NetworkChangeNotifier::ConnectionType connection_type =
net::NetworkChangeNotifier::GetConnectionType();
printf("connection_type %s\n",
net::NetworkChangeNotifier::ConnectionTypeToString(connection_type));
net::NetworkInterfaceList network_interface_list;
if (net::GetNetworkList(&network_interface_list,
net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES)) {
for (auto n : network_interface_list) {
printf("network interface name --- %s ---------------\n", n.name.c_str());
printf("network interface friendly_name %s\n", n.friendly_name.c_str());
printf("network interface connection_type %s\n",
net::NetworkChangeNotifier::ConnectionTypeToString(n.type));
printf("network interface address %s\n", n.address.ToString().c_str());
}
}
}