wifi连接上后是怎么提供网络的?

干了六个月的网络协议栈,又回到了wifi老本行,所以我最近又开始研读 Android wifi fwk的源码了
之前还在干wifi的时候就思考过一个问题,wifi区别于蓝牙的一个很明显的点是,wifi可以提供 access to Internet
所以我想看看wifi连接成功后是怎么给上层app提供网络的

前言:研读过程中发现整个机制中有大量的类,且它们的命名非常符合自身的功能,这是我觉得oop语言很有趣也是很容易上手的原因
与之前解决 WNS 选网过程一样,解读的过程中我会尝试给出一个大概的通俗语言描述的模型

注册 NetworkOffer

WifiService(SystemService的子类)在完全开机后,会执行 handleBootCompleted() 方法,注册自己魔改的几个NetworkFactory
我们只关注 WifiNetworkFactory

//WifiServiceImpl.java
public void handleBootCompleted() {mWifiThreadRunner.post(() -> {Log.d(TAG, "Handle boot completed");//...mWifiInjector.getWifiNetworkFactory().register();mWifiInjector.getUntrustedWifiNetworkFactory().register();mWifiInjector.getOemWifiNetworkFactory().register();});
}

NetworkFactory register动作主要做的是

  1. ConnectivityManager.registerNetworkProvider(new NetworkProvider)
  2. handleOfferNetwork -> ConnectivityManager.offerNetwork
//NetworkFactoryImpl.java
private void register(final String logTag, final boolean listenToAllRequests) {mProvider = new NetworkProvider(mContext, NetworkFactoryImpl.this.getLooper(), logTag) {@Overridepublic void onNetworkRequested(@NonNull NetworkRequest request, int score,int servingProviderId) {handleAddRequest(request);}@Overridepublic void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {handleRemoveRequest(request);}};((ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).registerNetworkProvider(mProvider);if (listenToAllRequests) {sendMessage(obtainMessage(CMD_LISTEN_TO_ALL_REQUESTS));} else {sendMessage(obtainMessage(CMD_OFFER_NETWORK));}
}//handle CMD_OFFER_NETWORK msg 的逻辑
//此处 mScore == 0
private void handleOfferNetwork(@NonNull final NetworkScore score) {mProvider.registerNetworkOffer(score, mCapabilityFilter, mExecutor, mRequestCallback);
}
//NetworkProvider.java
public void registerNetworkOffer(@NonNull final NetworkScore score,@NonNull final NetworkCapabilities caps, @NonNull final Executor executor,@NonNull final NetworkOfferCallback callback) {mContext.getSystemService(ConnectivityManager.class).offerNetwork(providerId, score, caps, proxy);
}

简单总结:到这里,wifi fwk已经成功地向 CS 注册了一个 NetworkProvider,并且经由这个 NetworkProvider 给出了一个 NetworkOffer
这个 NetworkOffer 就是用来去 satisfy 上层app发起的 NetworkRequest 的,当 CS match 某NetworkOffer 和 某NetworkRequest 的时候,就意味着这个app发起的网络请求将由匹配的网络来处理
不过,wifi fwk给出的这个 NetworkOffer尚处于不能 handle network request 的状态,因为它的 score 是 0

创建NetworkAgent

wifi fwk STA mode的状态机进入 L2ConnectedState 后(L2表示关联上了,之后会进行DHCP,拿到ip后进入L3ConnectedState),会创建 NetworkAgent

//ClientModeImpl.java
//class L2ConnectedState的EA
mNetworkAgent = mWifiInjector.makeWifiNetworkAgent(nc, mLinkProperties, naConfig,mNetworkFactory.getProvider(), new WifiNetworkAgentCallback());
mWifiScoreReport.setNetworkAgent(mNetworkAgent);

如上代码所示,WifiScoreReport 持 WifiNetworkAgent ,它会根据wifi链路状态实时地更新wifi网络在 CS 中的评分(通过调用 sendNetworkScore 方法)

创建 NetworkAgent 触发的一系列动作如下
最主要的是 创建NetworkMonitor

//WifiNetworkAgent.java
public WifiNetworkAgent(@NonNull Context context,@NonNull Looper looper,@NonNull NetworkCapabilities nc,@NonNull LinkProperties lp,@NonNull NetworkAgentConfig config,@Nullable NetworkProvider provider,@NonNull Callback wifiNetworkAgentCallback) {super(context, looper, TAG, nc, lp, ConnectedScore.WIFI_INITIAL_SCORE, config, provider);register();
}//NetworkAgent.java
public Network register() {synchronized (mRegisterLock) {final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context.getSystemService(Context.CONNECTIVITY_SERVICE);mNetwork = cm.registerNetworkAgent(new NetworkAgentBinder(mHandler),new NetworkInfo(mInitialConfiguration.info),mInitialConfiguration.properties, mInitialConfiguration.capabilities,mInitialConfiguration.score, mInitialConfiguration.config, providerId);}return mNetwork;
}//ConnectivityService.java
private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo,LinkProperties linkProperties, NetworkCapabilities networkCapabilities,NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId,int uid) {LinkProperties lp = new LinkProperties(linkProperties);final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);final NetworkAgentInfo nai = new NetworkAgentInfo(na,new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),this, mNetd, mDnsResolver, providerId, uid, mLingerDelayMs,mQosCallbackTracker, mDeps);mDeps.getNetworkStack().makeNetworkMonitor(nai.network, name, new NetworkMonitorCallbacks(nai));return nai.network;
}

NetworkMonitor创建成功后,CS 会触发 onNetworkMonitorCreated 回调,处理逻辑是 mNetworkMonitor.start()
我们在 main log中经常可以看到 NetworkMonitor http/https/dns probe fail,这说明 NetworkMonitor 的功能是受控去 probe 指定url,根据返回的status code判断当前链接的状态

实时更新 Network

wifi fwk STA mode处于 L2ConnectedState,接收到 CMD_IP_CONFIGURATION_SUCCESSFUL msg(意味着DHCP完成,这个网络有了自己的ip)

//ClientModeImpl.java
case CMD_IP_CONFIGURATION_SUCCESSFUL: {if (getConnectedWifiConfigurationInternal() == null || mNetworkAgent == null) {mWifiNative.disconnect(mInterfaceName);} else {handleSuccessfulIpConfiguration();sendConnectedState();transitionTo(mL3ConnectedState);}break;
}private void sendConnectedState() {mNetworkAgent.markConnected();sendNetworkChangeBroadcast(DetailedState.CONNECTED);
}//NetworkAgent.java
public void markConnected() {mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null /* reason */,mNetworkInfo.getExtraInfo());queueOrSendNetworkInfo(mNetworkInfo);
}

markConnected 之后,NetworkAgent 会把更新了状态的 NetworkInfo 同步给 CS
同步过程如下

//NetworkAgentInfo.java
public void sendNetworkInfo(@NonNull NetworkInfo info) {mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_INFO_CHANGED,new Pair<>(NetworkAgentInfo.this, info)).sendToTarget();
}//ConnectivityService.java
//NetworkStateTrackerHandler handle this msg
case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {NetworkInfo info = (NetworkInfo) arg.second;updateNetworkInfo(nai, info);break;
}private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info) {if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {rematchAllNetworksAndRequests();} else if (state == NetworkInfo.State.DISCONNECTED) {networkAgent.disconnect();}
}

rematchAllNetworksAndRequests 做的事情便是重新匹配 Network 和 NetworkRequest
我们在main log中经常可以见到 CS NetworkRequest reassign 的打印,这代表原来由某网络负责的NetworkRequest被分配给另一网络处理了
任何一个网络的状态稍有改变都会触发这个动作

WifiScoreReport sendNetworkScore 后触发的流程与上面类似,只不过 msg 换成了 EVENT_NETWORK_SCORE_CHANGED

//ConnectivityService.java
private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) {nai.setScore(score);rematchAllNetworksAndRequests();
}

总结

WifiService 在开机完成后就像 CS 注册了一个 NetworkProvider,并经由这个NetworkProvider注册了一个 NetworkOffer,只不过处于一个无法向外提供服务的状态。
当连接上某wifi(完成了数据链路层的连接)后,wifi 创建一个 NetworkAgent 用于管理这个网络,同时CS创建一个 NetworkMonitor 用于监管这个网络。
当DHCP完成,wifi网络理论上可以与外界通信后,wifi 的NetworkAgent实时地告知 CS 其NetworkInfo 的改动, CS 会重新调整 NetworkRequest 与 Network 的匹配关系。

后续研读计划

这个方面实际要研读的东西还有很多,一开始是想要搞懂wifi连接上后如何提供网络的

看和写的过程中意识到还应该系统地弄清楚这些问题

  • wifi 改动网络评分的细节(WifiNetworkAgent + WifiScoreReport)
  • CS rematch 的细节(显然CS绝对不是唯评分论的单一匹配机制)
  • macth后一个NetworkRequest是怎么被satisfy的 (数据通路是怎样的)

后记:理解了这个模型,大概可以搞清wifi连接上后是怎么提供网络的了,但是搞清楚这个对于日常工作做trouble shooting有什么帮助吗?
貌似也没有多大帮助
哈哈哈哈,图一乐

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/732243.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue2 div滚动条下拉到底部时触发事件(懒加载) 超级简易版本的懒加载

文章目录 导文文章重点内容效果展示&#xff1a;代码展示这些方法适用于哪些场景 总结 导文 vue2 div滚动条下拉到底部时触发事件(懒加载) 超级简易版本的懒加载 文章重点 内容效果展示&#xff1a; 当div拉到底部的时候&#xff1a; 编辑器返回&#xff1a; 代码展示 在…

substr函数踩坑

##hive和impala的substr函数比对 ###在hive中substr函数使用 select substr(name,0,5) from bd_test; 结果&#xff1a;12345 select substr(name,1,5) from bd_test; 结果&#xff1a;12345 ###impala中substr函数使用 select substr(name,0,5) from bd_test; 结果&#xff…

JAVA后端开发面试基础知识(十)——设计模式

创建型模式 创建型模式的作用就是创建对象&#xff0c;说到创建一个对象&#xff0c;最熟悉的就是 new 一个对象&#xff0c;然后 set 相关属性。但是&#xff0c;在很多场景下&#xff0c;我们需要给客户端提供更加友好的创建对象的方式&#xff0c;尤其是那种我们定义了类&am…

BJFU|计算机网络缩写对照表

之前有过这个题型&#xff0c;但23年没考&#xff0c;所以按需准备 A ACK (ACKnowledgement) 确认 ADSL (Asymmetric Digital Subscriber Line) 非对称数字用户线 API (Applicatin Programming Interface) 应用编程接口 ARP (Address Resolution Protocol) 地址解析协议 ARQ (…

Git - Protocol

4.1 Git on the Server - The Protocols 至此&#xff0c;你应该可以完成大部分日常工作&#xff0c;而这些工作都需要用到 Git。不过&#xff0c;要在 Git 上进行任何协作&#xff0c;你都需要一个远程 Git 仓库。虽然从技术上讲&#xff0c;你可以推送改动到个人仓库&#xf…

银河麒麟服务器操作系统V10【vnc配置多用户登录】

1.添加多用户&#xff08;规划kingbase使用5901窗口&#xff0c;root使用5903&#xff09;&#xff1b; adduser kingbase 2.配置文件&#xff1b; cp -rp /lib/systemd/system/vncserver.service /etc/systemd/system/vncserver:1.servicecp -rp /lib/systemd/system/vncse…

【黑马程序员】Python初始

初始Python Python应用场景 什么是编程语言 安装Python开发环境 Python官网 选择Download 选择对应的Python版本和所要下载的操作系统 下载后直接下一步下一步即可安装成功 测试安装效果 重命名python命令让其使用Python3 echo alias python"python3" >…

编程笔记 Golang基础 046 mssql数据库连接与操作

编程笔记 Golang基础 046 mssql数据库连接与操作 一、连接与操作二、全局连接三、数据库连接字符串四、应用示例小结 数据库操作是现代软件系统不可或缺的一部分&#xff0c;对软件的功能实现、性能优化、数据安全等方面起着至关重要的作用。Go语言中连接和操作Microsoft SQL S…

知名比特币质押协议项目Babylon确认参加2024年在香港数码港举办的Hack.Summit()2024区块链开发者大会。

知名比特币质押协议项目Babylon确认参加2024年在香港数码港举办的Hack.Summit()2024区块链开发者大会。作为比特币生态的领军项目&#xff0c;Babylon积极参与全球区块链领域的交流与合作&#xff0c;此次出席大会将为其提供一个展示项目进展、交流技术与创新思路的重要平台。B…

2402. 2-SAT 问题(tarjan,2-SAT模板题)

活动 - AcWing 给定 n 个还未赋值的布尔变量 x1∼xn。 现在有 m 个条件&#xff0c;每个条件的形式为 “xi 为 0/1 或 xj 为 0/1 至少有一项成立”&#xff0c;例如 “x1 为 1 或 x3 为 0”、“x8 为 0 或 x4 为 0” 等。 现在&#xff0c;请你对这 n 个布尔变量进行赋值&am…

acwing算法提高之数据结构--树状数组

目录 1 专题介绍2 训练 1 专题介绍 本专题用来汇总使用树状数组算法求解的题目。 应用场景&#xff1a;给你长度为n的数组nums&#xff0c;可以改变第i个数的大小&#xff0c;求数组下标区间[left, right]内的前缀和。要求时间复杂度不超过 O ( l o g N ) O(logN) O(logN)。 …

使用 MySQL 实现 Java 版的 hashCode 函数

前提 MySQL 数据库的编码需要设置为 utf8 或 utf8mb4&#xff0c;因为下面给出的代码是以用 utf8 编码储存数据为前提的。 MySQL Function drop function if exists utf8_unicode; create function utf8_unicode(str varchar(1)) returns bigint begindeclare num_utf8 bigi…

【GB28181】SIP协议实践之Windows下VS2019编译eXosip、osip,测试(附工程源码,一键打开编译)

引言 SIP开源库或者GB28181,这里选择了osip和eXosip,但是这两个库的编译使用有些麻烦,源码下来之后编译会出现很多问题,网上也没有找到完整的编译介绍,只能一步一步的找办法解决,以下帮大家整理编译过程。 如果不想编译,可以跳转文章末尾链接直接下载相应工程直接编译即…

登录校验认证

会话技术 会话&#xff1a;用户打开浏览器&#xff0c;访问web服务器的资源&#xff0c;会话建立&#xff0c;直到有一方断开连接&#xff0c;会话结束。在一次会话中可以包含多次请求和响应。 会话跟踪&#xff1a; 一种维护浏览器状态的方法&#xff0c;服务器需要识别多次请…

Aop注解+Redis解决SpringBoot接口幂等性(源码自取)

目录 一、什么是幂等性&#xff1f; 二、哪些请求天生就是幂等的&#xff1f; 三、为什么需要幂等 1.超时重试 2.异步回调 3.消息队列 四、实现幂等的关键因素 关键因素1 关键因素2 五、引入幂等性后对系统的影响 六、Restful API 接口的幂等性 实战Aop注解redis解…

计算机网络——计算机网络的性能

计算机网络——计算机网络的性能 速率带宽吞吐量时延时延宽带积往返时间RTT利用率信道利用率网络利用率 我们今天来看看计算机网络的性能。 速率 速率这个很简单&#xff0c;就是数据的传送速率&#xff0c;也称为数据率&#xff0c;或者比特率&#xff0c;单位为bit/s&#…

神经网络 梯度与神经元参数w、b关系;梯度与导数关系

参考&#xff1a;https://blog.csdn.net/weixin_44259490/article/details/90295146 视频&#xff1a;https://www.bilibili.com/video/BV1a14y167vh 概念 梯度与w的关系可以用梯度下降公式来表示&#xff1a;ww−α ∂ c o s t ∂ w \frac{\partial cost}{\partial w} ∂w∂…

vs创建asp.net core webapi发布到ISS服务器

打开服务器创建test123文件夹&#xff0c;并设置共享。 ISS配置信息&#xff1a; 邮件网站&#xff0c;添加网站 webapi asp.net core发布到ISS服务器网页无法打开解决方法 点击ISS Express测试&#xff0c;可以成功打开网页。 点击生成&#xff0c;发布到服务器 找到服务器IP…

idm对比aria2哪个好 aria2和idm哪个快 Aria2和IDM的原理

一、idm对比aria2哪个好 下面对aria2和idm进行对比&#xff0c;看看哪款更好。 idm: 优势&#xff1a; 1&#xff09;可将下载速度提升5倍以上&#xff1b; 2&#xff09;界面友好&#xff0c;操作简便&#xff1b; 3&#xff09;支持多个主流的浏览器&#xff1b; 4&am…

基于Vue的娱讯移动端APP前端设计与实现

目 录 摘 要 Abstract 引 言 1绪论 1.1课题背景及目的 1.1.1移动端APP发展简介 3 1.1.2移动端APP的优势 3 1.2前端开发相关技术 1.2.1前端开发工具介绍 3 1.2.2 前端开发相关技术介绍 4 1.3本章小结 2系统分析 2.1功能需求分析 2.2系统工作流程 2.3本章小结 3系统设…