Android 网络 --framework层面 -two

在Android 网络 --framework层面-1 中大致描述了android 网络 fwk涉及到一些重要类,本章针对这些较为详细的介绍学习下

NetworkAgent

NetworkAgent 是CS(ConnectivityService)和链路网络管理者(如WifiStateMachine、DataConnection)之间的信使,从CS的角度看NetworkAgent代表了一个网络实体

WIFI在L2连接成功(L2connected 关联4次握手成功 )后构建对象。通过NetworkAgent,WifiStateMachine可以向CS:

  1. 更新网络状态 NetworkInfo(断一些开、连接中、已连接等)
  2. 更新链路配置 LinkProperties(本机网口、IP、DNS、路由信息等)
  3. 更新网络能力 NetworkCapabilities(信号强度、是否收费等)

CS可以向WifiStateMachine:

  1. 更新网络有效性(即NetworkMonitor的网络检测结果)
  2. 禁止自动连接
  3. 由于网络不可上网等原因主动断开网络

data 是在DataConnection进入DcActiveState 状态(拨号成功)构造对象, 此时已经获取到ip dns网络信息,区别于WIFI的L2connected 状态
DataConnection 和 CS交互的信息有很多相似点,这里不在一一罗列了

NetworkAgent 注册的代码片段
在NetworkAgent的构造函数会调用CS的registerNetworkAgent ,Messenger是CS和链路网络管理者"业务往来"的方式

cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni), new LinkProperties(lp), 
						new NetworkCapabilities(nc), score, misc);

NetworkAgent在CS中与之对应的是NetworkAgentInfo

final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
        new Network(reserveNetId()), new NetworkInfo(networkInfo), lp,
        new NetworkCapabilities(networkCapabilities), currentScore,
        mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this);
  1. NetworkAgentInfo 是对NetworkAgent 在CS的包装
  2. Messenger :CS通过这个messenger调用NetworkAgent(client端)的方法
  3. mTrackHandler :NetworkAgent通过TrackHandler调用的cs的方法,本质也是包装为messenger
  4. reserveNetId() 生成网络networkid,这个网络id在数据包打mark的时候会用到

registerNetworkAgent最终会调用到CS中的handleRegisterNetworkAgent

private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
    if (VDBG) log("Got NetworkAgent Messenger");
    mNetworkAgentInfos.put(na.messenger, na);
    synchronized (mNetworkForNetId) {
        mNetworkForNetId.put(na.network.netId, na);
    }
    na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
    NetworkInfo networkInfo = na.networkInfo;
    na.networkInfo = null;
    updateNetworkInfo(na, networkInfo);
}

所有的NetworkAgentInfo会保存在mNetworkForNetId中!!

private final SparseArray<NetworkAgentInfo> mNetworkForNetId =
        new SparseArray<NetworkAgentInfo>();

最终会调用到

 updateNetworkInfo(na, networkInfo);

对于这个方法 处理registerNetworkAgent情境下:

  1. DcNetworkAgent (数据网络) 在 networkinfo的state在进入DcActiveState状态后设置为NetworkInfo.State.CONNECTED
  2. WifiNetworkAgent (WIFI网络)在进入mConnectedState-----ip地址配置成功后 sendConnectedState()进入mConnectedState状态

如果networkAgent.created=false 该网络从未创建过,且NetworkInfo.State.CONNECTED
在netd里面创建一个PhysicalNetwork,一个netid 对一个PhysicalNetwork(netd PhysicalNetwork .cpp)

mNetd.createPhysicalNetwork(networkAgent.network.netId,
        getNetworkPermission(networkAgent.networkCapabilities));

如果networkAgent.everConnected = false ,从来没有连接过且 NetworkInfo.State.CONNECTED 更新链路信息,包括 updateInterfaces、updateMtu、updateTcpBufferSizes、updateRoutes、updateDnses

  1. updateInterfaces通过调用netd的addInterfaceToNetwork,此例子是通过PhysicalNetwork的
  2. addInterface 方法,给IncomingPacket的打mark 和 设置策略路由
  3. 关于和netd交互的两点,会在netd章节中学习下

最后rematchNetworkAndRequests网络,因为只有一个网络传入REAP

REAP 意思就是如果没有一个network request匹配上这个NetworkAgentInfo,就会tear down 该network,这个很好理解,既然没有网络请求需要这个NetworkAgentInfo,那就没有存在的必要了

rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP, now);

rematchNetworkAndRequests–非常核心的方法!!

理解这个方法,CS基本掌握一大半了!!

rematchNetworkAndRequests(NetworkAgentInfo newNetwork,
        ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now)
  1. 这个方法的做的事情总结一句话 Handles a network appearing or improving its score.
  2. 新的NetworkAgentInfo出来,要重新评估所有的NetworkRequests,如果这个网络是最好的网络,会将这些NetworkRequests reassigns到这个新网络, 比如数据网络连接的情况下,wifi连接成功且网络判通成功,这时候一些网络请求的NetworkRequests 要reassigns 到wifi的NetworkAgentInfo
  3. Lingers任何一个不再需要的validated Networks,理解 “不再需要”,wifi连接的情况下,data网络正常是会linger的,但是如果此时有一个或多个NetworkRequest的指定的transportType为NetworkCapabilities.TRANSPORT_CELLULAR 此时不会linger这个数据网络,另外这个网络是VPN.也不会被linger
  4. 如果一个不需要的网络,就是被linger的网络,会执行Tears down newNetwork ,导致networkagent调用unwanted()方法 网络interface 都会被关闭(可以通过ifconfig 中消失掉来验证)
  5. reapUnvalidatedNetworks 最后一个网络会传REAP,导致网络被tear down

"理解最好的网络!!!----------------------该方法核心!!! "
把newNetwork 和当前所有的newtworkRequest (保存在mNetworkRequests)做satisfies,如果“满足”了,
且下面三种条件之一成立的:|| 或的关系

  1. currentNetwork == null 当前的网络为null,比如在无任何网络的情况下,打开数据网络,"当前的网络为null ",当然会创建新的默认网络
  2. isBestMobileMultiNetwork() — 此方法未研究–记得7.0没有,应该和双卡有关系,貌似选择默认数据网络卡会走这个
  3. currentNetwork.getCurrentScore() < score 当前网络分数小于newNetwork的分数,会切换default网络

把request从currentNetwork remove掉,并添加到newNetwork中,如果currentNetwork没有一个网络request,自然就需要 linger掉了!!

把request从currentNetwork remove掉
//把request从currentNetwork remove掉
currentNetwork.removeRequest(nri.request.requestId);  
// 把nri.request 添加到mLingerTimerForRequest
currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs);
// 把request添加到新的newNetwork
setNetworkForRequest(nri.request.requestId, newNetwork);

如果满足再满足isDefaultRequest条件下:
会导致新的default网络的出现,看下makeDeault到底干啥,设置default的路由的(netd章节会介绍学习下)
// Log 0 -> X and Y -> X default network transitions, where X is the new default.

private void makeDefault(NetworkAgentInfo newNetwork) {
    if (DBG) log("Switching to new default network: " + newNetwork);
    try {
        mNetd.setDefaultNetId(newNetwork.network.netId);
    } catch (Exception e) {
        loge("Exception setting default network :" + e);
    }
     // 通过prop可以读取dns的直
    setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers());
}

总结:
本章介绍学习了NetworkAgent和CS中重要的rematchNetworkAndRequests方法,理解这个方法是理解CS的关键点,甚者可以说是理解android fwk 网络的关键点 !!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值