当前位置: 首页 > news >正文

Android第五次面试总结之网络篇(修)

一、域名解析到服务器的过程(DNS 解析流程)

当应用发起网络请求(如https://www.example.com)时,操作系统需先将域名转换为服务器 IP 地址,这一过程通过 DNS(域名系统) 完成,具体步骤如下:

1. 客户端本地缓存查询(递归查询)
  • 浏览器缓存:浏览器会首先检查自身缓存(如 Chrome 通过chrome://net-internals/#dns查看),存储近期解析过的域名 - IP 映射,有效期由 DNS 响应的TTL(生存时间)决定。
  • 系统缓存:若浏览器未命中,操作系统(Android)会查询本地 DNS 缓存(可通过android.system.DnsCache类访问,但需权限)。
  • Hosts 文件:Android 系统会读取/system/etc/hosts文件(需 root 权限)或应用自定义的 hosts 文件(如通过 VPN 代理设置),优先于 DNS 服务器查询。
2. DNS 服务器迭代查询

若本地缓存未命中,客户端会向 本地 DNS 服务器(如运营商提供的 DNS,或用户手动设置的公共 DNS 如 8.8.8.8)发起查询,该过程为 迭代查询

  • 根域名服务器:本地 DNS 服务器首先查询根域名服务器(全球 13 组,负责.com.cn等顶级域名),根服务器返回对应顶级域名服务器(TLD Server)的地址。
  • 顶级域名服务器:如.com服务器,返回域名example.com的权威域名服务器(Authoritative Server)地址。
  • 权威域名服务器:存储example.com的 DNS 记录(如 A 记录、AAAA 记录),返回最终的 IP 地址(如192.168.1.1)。
3. 返回 IP 地址

本地 DNS 服务器将解析结果缓存并返回给客户端,后续请求可直接使用 IP 地址建立连接。

二、DNS 解析过程的核心机制

1. 递归查询 vs 迭代查询
  • 递归查询(客户端→本地 DNS 服务器):客户端只需发送一次查询请求,本地 DNS 服务器负责全程查询并返回结果(类似 “一站式服务”)。
  • 迭代查询(本地 DNS 服务器→根→TLD→权威服务器):每一步查询返回下一级服务器地址,需多次交互(类似 “分步导航”)。
2. DNS 记录类型
  • A 记录:域名→IPv4 地址(最常用)。
  • AAAA 记录:域名→IPv6 地址。
  • CNAME 记录:别名解析(如www.example.comexample.com)。
  • MX 记录:邮件服务器解析。
  • TXT 记录:存储文本信息(如 SPF 反垃圾邮件策略)。

三、DNS 请求使用的协议:UDP 为主,TCP 为辅

1. 默认使用 UDP(端口 53)
  • 原因
    • 轻量化:DNS 查询 / 响应数据量小(通常 < 512 字节),UDP 无需建立连接,延迟更低(适合移动端弱网场景)。
    • 速度优先:移动端网络环境复杂,UDP 的无连接特性避免了 TCP 三次握手的耗时。
  • Android 中的实现
    • 系统通过Dns类(如Dns.resolve())发起 UDP 查询,底层调用 libresolv库。
2. 何时使用 TCP?
  • DNS 区域传输:主从 DNS 服务器同步数据时,因数据量大(可能超过 UDP 缓冲区),使用 TCP 保证可靠传输。
  • 响应超过 512 字节:当 DNS 响应数据超过 UDP 最大载荷(512 字节),服务器会在响应中标记TC(Truncated)标志,客户端自动切换为 TCP 重新查询。

四、UDP 不可靠性的解决方案

虽然 UDP 不保证可靠传输,但 DNS 通过以下机制弥补缺陷:

1. 客户端超时重传
  • 客户端发送 UDP 查询后,若未在超时时间(通常 2-5 秒)内收到响应,会自动重试(默认重试次数 2-3 次)。
  • Android 源码中,DnsResolver类通过AsyncTask实现异步查询,超时后触发重试逻辑。
2. DNS 服务器的可靠性设计
  • 冗余部署:权威 DNS 服务器通常部署多副本,避免单点故障(如阿里云 DNS、Cloudflare DNS)。
  • TCP 作为备用:当 UDP 查询失败(如频繁超时),客户端会尝试通过 TCP 重新请求(如 HTTPS 场景下的 DoH(DNS over HTTPS)强制使用 TCP)。
3. 移动端优化
  • 预解析:在应用启动或空闲时,提前解析常用域名(如通过android:usesCleartextTraffic配置或DnsPrefetch策略),减少实时查询延迟。
  • HTTPS 化:使用 DoH(RFC 8484)或 DoT(DNS over TLS),通过 HTTPS/TLS 加密 DNS 流量,避免 UDP 被劫持,同时利用 TCP 的可靠性。

五、TCP 滑动窗口:流量控制与高效传输

1. 核心作用

滑动窗口是 TCP 实现 流量控制 和 拥塞控制 的关键机制,允许发送方在收到确认前批量发送数据,提升传输效率。

2. 工作原理
  • 窗口大小:接收方在 ACK 报文中告知发送方自己当前的接收缓冲区剩余空间(即 “接收窗口”),发送方根据此动态调整 “发送窗口” 大小。
  • 滑动过程
    1. 发送方将数据分割为多个段(Segment),放入发送窗口,无需等待每个段的 ACK 即可连续发送。
    2. 接收方收到数据后,返回 ACK 并更新接收窗口(如ACK 1000 + 窗口大小2000表示 “前 1000 字节已接收,剩余可接收 2000 字节”)。
    3. 发送方根据 ACK 移动窗口,发送窗口右侧未确认的数据会触发超时重传。
3. 滑动窗口的三个阶段(结合 Android 网络优化)
  • 慢启动(Slow Start):初始窗口较小(如 1-2 个 MSS),逐步指数级增长,避免网络拥塞(如 Android 下载大文件时的初始阶段)。
  • 拥塞避免(Congestion Avoidance):窗口增长到阈值后,转为线性增长,防止网络过载(如 OkHttp 的连接池管理)。
  • 快速重传与恢复(Fast Retransmit/Fast Recovery):若收到 3 个重复 ACK,判定数据段丢失,立即重传而不等待超时(提升弱网环境下的稳定性)。
4. Android 中的实际应用
  • OkHttp 连接优化:通过ConnectionSpec配置 TCP 参数(如窗口大小、超时时间),结合滑动窗口机制减少延迟。
  • NDK 开发:在 C/C++ 层通过setsockopt()设置 TCP 窗口选项(如TCP_NODELAY禁用 Nagle 算法,配合滑动窗口提升实时数据传输效率)。

总结(面试应答要点)

  1. DNS 解析流程:从本地缓存到递归 / 迭代查询,逐层解析域名到 IP,结合 TTL 缓存提升性能。
  2. DNS 协议选择:默认 UDP(低延迟),必要时切换 TCP(大数据量 / 可靠性),移动端可通过预解析和 DoH 优化。
  3. UDP 可靠性:依赖客户端超时重传、服务器冗余及 TCP 备用通道,结合现代加密方案(DoH/DoT)增强安全性。
  4. TCP 滑动窗口:通过动态调整发送 / 接收窗口实现流量控制,分阶段优化传输效率,是 HTTP/2 多路复用、QUIC 协议的底层基础。

扩展追问:

一、DNS 挟持的核心原理(面试必问基础)

1. 基础概念与攻击本质

DNS 挟持是通过篡改域名解析结果,将用户请求的域名(如www.bank.com)指向恶意 IP 地址,导致用户访问钓鱼网站或被劫持流量的攻击行为。其核心逻辑是破坏域名到 IP 的映射关系,分为以下三个阶段:

  • 请求阶段:用户设备向 DNS 服务器发送域名解析请求(如nslookup www.example.com)。
  • 篡改阶段:攻击者通过中间人攻击、路由器漏洞或恶意软件,在 DNS 查询路径中替换正确的 IP 地址为恶意地址。
  • 重定向阶段:用户设备根据伪造的 IP 连接到恶意服务器,导致数据泄露或服务中断。
2. Android 特有的攻击场景
  • 恶意 APP 篡改本地配置
    攻击者通过WRITE_SETTINGS权限修改设备 DNS 服务器地址,或篡改/system/etc/hosts文件(需 root 权限)15。
    // 示例:恶意APP修改DNS设置(需权限)  
    Settings.Global.putString(context.getContentResolver(),  Settings.Global.ETH0_DNS1, "192.168.1.253"); // 篡改DNS服务器  
    
  • 公共 Wi-Fi 中间人攻击
    攻击者在咖啡店等场景伪造热点,通过 DNS 欺骗将用户流量导向钓鱼页面14。
  • 运营商层面劫持
    部分 ISP 违规插入广告页面(如访问不存在的域名时跳转广告),或篡改 DNS 响应2。

二、Android 系统的 DNS 解析流程(面试重点:技术实现)

1. 解析流程与关键组件

Android 设备的 DNS 解析分为系统层应用层两个层面:

  • 系统层解析
    1. 设备向本地 DNS 服务器(如运营商 DNS)发送 UDP/TCP 请求。
    2. DNS 服务器递归查询根域名服务器,获取目标 IP 地址。
    3. 系统缓存解析结果(TTL 时间内复用)。
  • 应用层解析
    1. 应用通过InetAddress.getByName()或网络库(如 OkHttp)发起解析。
    2. 若系统 DNS 被劫持,解析结果可能指向恶意 IP34。
2. Android 版本差异与限制
  • Android 7.0(API 24)限制
    禁止普通应用直接修改全局 DNS 设置,需通过 VPN 或设备管理员权限配置21。
  • Android 9+(API 28)支持 DoT
    可通过系统设置或代码启用加密 DNS(如DnsOverTls),防止中间人篡改910。
  • Android 10+(API 29)支持 DoH
    部分浏览器(如 Chrome)默认启用 DNS over HTTPS,加密解析过程27。

三、DNS 挟持的检测方法(面试高频:代码实现)

1. 编程层面检测
  • 对比官方 IP 地址
    try {  InetAddress address = InetAddress.getByName("www.google.com");  String expectedIp = "142.250.186.14"; // 谷歌官方IP(需动态更新)  if (!expectedIp.equals(address.getHostAddress())) {  // DNS解析异常,触发警告  showToast("DNS可能被劫持!");  }  
    } catch (UnknownHostException e) {  e.printStackTrace();  
    }  
    
  • 多 DNS 服务器校验
    同时请求 Google DNS(8.8.8.8)和 Cloudflare DNS(1.1.1.1),对比解析结果是否一致4。
2. 系统 API 获取 DNS 配置
  • Android 10 + 获取当前 DNS 服务器
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {  NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);  List<InetAddress> dnsServers = capabilities.getDnsServers();  // 检查是否包含恶意DNS(如192.168.1.253)  
    }  
    
  • 面试追问:为什么 Android 7.0 后禁止直接修改全局 DNS?
    :出于安全考虑,防止恶意 APP 篡改网络设置,需通过Settings或设备管理员权限配置21。

四、Android 开发中的防护方案(高频考点:代码与系统配置)

1. 强制使用 HTTPS 并校验证书
  • 网络安全策略配置
    AndroidManifest.xml中禁用明文流量,并固定证书:
    <network-security-config>  <base-config cleartextTrafficPermitted="false">  <trust-anchors>  <certificates src="system" /> <!-- 仅信任系统证书 -->  <certificates src="@raw/bank_ca" /> <!-- 证书固定 -->  </trust-anchors>  </base-config>  
    </network-security-config>  
    
  • 面试考点:证书固定(Certificate Pinning)的作用?
    :即使 DNS 被劫持,若服务器证书与本地固定证书不匹配,请求会失败,防止连接到伪造站点18。
2. 自定义 DNS 解析器(绕过系统 DNS)
  • 使用 OkHttp 自定义 DNS
    OkHttpClient client = new OkHttpClient.Builder()  .dns(new Dns() {  @Override  public List<InetAddress> lookup(String hostname) throws UnknownHostException {  // 自定义DNS解析逻辑(如使用阿里云公共DNS)  return InetAddress.getAllByName(hostname);  }  })  .build();  
    
  • 面试问题:为什么使用 HTTPDNS 能防劫持?
    :HTTPDNS 通过 HTTP 协议直接向权威服务器查询 IP,绕过运营商 DNS,避免劫持1128。
3. 启用加密 DNS 协议(DoT/DoH)
  • Android 9 + 配置 DoT
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {  DnsOverTls dnsOverTls = DnsOverTls.create(network, "dns.cloudflare.com");  // 应用层使用该DNS解析器  
    }  
    
  • DoT 与 DoH 的区别
    • DoT:基于 TLS 协议,端口 853,传输层加密,Android 9 + 原生支持9。
    • DoH:基于 HTTPS 协议,端口 443,应用层加密,Android 10 + 浏览器支持27。
4. 检测本地 hosts 文件篡改
  • 读取 hosts 文件并校验
    try {  BufferedReader reader = new BufferedReader(new FileReader("/system/etc/hosts"));  String line;  while ((line = reader.readLine()) != null) {  if (line.contains("恶意域名") || line.contains("可疑IP")) {  // 触发安全警告  }  }  
    } catch (IOException e) {  e.printStackTrace();  
    }  
    

五、设备与系统层面的防护(面试需结合 Android 特性)

  1. 路由器与网络环境加固

    • 修改路由器默认密码,关闭远程管理权限,启用 DNS 防劫持功能(如小米路由器的 “DNS 过滤”)7。
    • 优先使用家庭 Wi-Fi,避免公共网络;必要时使用 VPN 加密流量14。
  2. 系统级防护策略

    • Android 9 + 私有 DNS
      在设置中配置私有 DNS(如dns.google),强制所有网络请求使用加密解析10。
    • 权限控制
      拒绝应用获取CHANGE_NETWORK_STATE等危险权限,防止篡改 DNS 设置12。
  3. 用户引导与教育

    • 提示用户手动设置公共 DNS(如 8.8.8.8),并定期检查网络配置24。
    • 关键场景(如网银)使用 HTTPS 并验证证书有效性6。

六、面试高频追问与参考答案

  1. “为什么 HTTPS 不能完全防止 DNS 挟持?”

    • 答:HTTPS 仅加密数据传输,若域名解析被劫持,用户会先连接到恶意服务器,后续加密无意义。需结合证书固定和加密 DNS(DoT/DoH)212。
  2. “Android 中如何实现 DNS 劫持的实时监控?”

    • 答:通过ConnectivityManager监听网络变化,每次网络切换后触发域名解析校验(如解析baidu.com并对比官方 IP),若连续多次解析错误则触发警报315。
  3. “如果用户连接的 Wi-Fi 被劫持,APP 如何保证安全?”

    • 答:① 强制使用 HTTPS 并启用证书固定;② 在 APP 内集成 DoH/DoT 解析器,绕过系统 DNS;③ 检测到异常解析时提示用户切换网络或使用 VPN69。
  4. “为什么有些 APP 在被 DNS 挟持后仍能正常访问?”

    • 答:若 APP 直接使用 IP 地址而非域名(如硬编码服务器 IP),或使用了内置的 DNS 解析库(如 OkHttp 自定义 DNS),可绕过系统 DNS 设置,但存在维护成本高、IP 变更无法自动更新的问题1117。

总结(面试加分项)

DNS 挟持的核心是篡改域名解析结果,而 Android 开发者需从 ** 应用层加密(HTTPS / 证书固定)、系统层配置(DoT/DoH/ 私有 DNS)、用户层引导(手动设置公共 DNS)** 三方面防范。

相关文章:

  • 【AI】OrinNX上安装RIVA-2.19.0,实现文本转语音
  • 第14讲:科研图表的导出与排版艺术——高质量 PDF、TIFF 输出与投稿规范全攻略!
  • 水安题库:水利水电安全员ABC精选练习题
  • MySQL多表操作
  • HCIE证书失效?续证流程与影响全解析
  • 一个SciPy图像处理案例的全过程
  • 小结:GRE VPN;IPSec
  • 【论文阅读/复现】RT-DETR的网络结构/训练/推理/验证/导出模型
  • 抱佛脚之学SSMSpringMVC数据绑定
  • JavaScript 作用域全面总结
  • Spring MVC 中解决中文乱码问题
  • 近期实践总结
  • 通信设备制造数字化转型中的创新模式与实践探索
  • 某高端制造企业知识中枢升级,基于悦数 Graph RAG 打造工业级「故障排查最强大脑」
  • 基于STM32、HAL库的DS28E25安全验证及加密芯片驱动程序设计
  • 有什么好用的工地全过程管理erp软件系统?如何推进数字化转型?
  • 去哪儿旅行 Bella Pre 分析
  • 53.[前端开发-JS实战框架应用]Day04-Bootstrap入门到项目实战
  • antd+react实现html图片预览效果
  • 面试手撕——快速排序
  • “75后”袁达已任国家发改委秘书长
  • 中国人寿一季度净利润288亿增39.5%,营收降8.9%
  • 10台核电新机组获核准,上海核电厂商独揽超500亿元订单
  • 一场与纪录并行的伦敦马拉松,超40项新世界纪录诞生
  • 深圳一季度GDP为8950.49亿元,同比增长5.2%
  • 中消协发布“五一”消费提示:践行“光盘行动”,抵制餐饮浪费