编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 01.崩溃捕获设计实践
  • 02.崩溃治理优化总结
  • 03.Native崩溃治理实践
  • 04.ANR监控设计实践
  • 05.CPU消耗优化实践
  • 06.卡顿监控设计实践
  • 07.卡顿治理优化实践
  • 08.网络分析与优化实践
  • 09.线程优化实践操作
  • 10.高性能图片优化方案
  • 11.OOM异常优化实践
  • 12.内存监控优化方案
  • 13.内存治理优化实践
  • 14.FPS监测设计实践
  • 15.进程优化设计实践
  • 16.App启动优化实践
  • 17.App页面UI优化实践
  • 18.App稳定性专项实践
  • 19.App瘦身优化实践
  • 20.常见代码优化实践
  • 21.移动端防抓包实践
  • 22.App磁盘沙盒实践
  • 23.Ping工具开发实践
  • 24.Gradle构建优化实践
  • 25.CodeReview实践总结

23.Ping工具开发实践

目录介绍

  • 01.ping是什么东西
  • 02.ping的基础说明
  • 03.ping在Android的应用
  • 04.ping工作过程
  • 06.ping后返回信息分析
  • 07.traceroute使用

01.ping是什么东西

  • ping是一个工具
    • Ping是Windows、Unix和Linux系统下的一个命令。ping也属于一个通信协议,是TCP/IP协议的一部分。
    • 利用“ping”命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障。
    • Ping发送一个ICMP(Internet Control Messages Protocol)即因特网信报控制协议,回声请求消息给目的地并报告是否收到所希望的ICMP echo (ICMP回声应答),用来检查网络是否通畅或者网络连接速度的命令。广义来说即发送一个数据包,根据返回的数据包得到丢包率及平均时间得出网络的连接状态。
  • 问题思考
    • 只有在安装 TCP/IP 协议之后才能使用该命令。否则无法使用
    • 可以理解为校验与远程计算机或本地计算机的连接状态
  • ping的作用有哪些
    • 我们可能都会遇到网站打不开,当出现不开的时候,我们也不知道是那里出了问题,不知道是不是解析出了问题还是网站的空间出了问题,这时候我们就可以通过ping来查找问题,看看网站能不能ping的通。

02.ping的基础说明

  • ping的用法
    • 例如命令:ping -t www.baidu.com 那么机器会一直ping www.baidu.com直到我们按Ctrl+C键来停止。
      • -l 定义发送数据包的大小,默认为32字节,我们利用它可以最大定义到65500字节。
    • 例如命令:ping -l 100 www.baidu.com,那么本地计算机就会用100字节的数据包去 ping www.baidu.com,系统默认的数据包是32字节,最大的字节数是65,527。
      • -n 定义向目标IP发送数据包的次数。
    • 例如命令:ping -n 10 www.baidu.com,那么本地计算机就会ping www.baidu.com10次,如果不加-n 参数的话,系统默认是ping4次。

03.ping在Android的应用

  • 为了检查网络,在android上也可以通过ping来查看是否网络通。
  • 实现方案有哪些
    • 通过后台线程执行ping命令的方式模拟traceroute的过程,缺点就是模拟过程较慢,timeout的出现比较频繁
    • 通过编译开源网络检测库iputilsC代码的方式对traceroute进行了套接字发送ICMP报文模拟,可以明显提高检测速度
      • 深入理解iputils网络工具:https://blog.csdn.net/fsdev/category_1212445.html
  • 关于代码ping的过程信息
    • 开启一个AsyncTask,在doInBackground方法中开始解析,这个是入口。
    • 添加头部信息,主要包括:开始诊断 + 输出关于应用、机器、网络诊断的基本信息 + 输出本地网络环境信息
    • tcp三次握手操作
      • 开始执行链接,这里有两个重要信息。一个是ip集合,另一个是InetAddress数组,遍历【长度是ip集合length】,然后执行请求
      • 创建socketAddress,有两个参数,一个是ip,一个是端口号80,然后for循环执行socket请求
      • 在执行socket请求的时候,如果有监听到超时SocketTimeoutException异常则记录数据,如果有异常则记录数据
      • 当出现发生timeOut,则尝试加长连接时间,注意连续两次连接超时,停止后续测试。连续两次出现IO异常,停止后续测试
      • 当然只要有一次完整执行成功的流程,那么则记录三次握手操作成功
    • 诊断ping信息, 同步过程。这个主要是直接通过ping命令监测网络
      • 创建一个NetPing对象,设置每次ping发送数据包的个数为4个
      • 然后ping本机ip地址,ping本地网观ip地址,ping本地dns。这个ping的指令是啥?这个主要是用java中的Runtime执行指令……
    • 开始诊断traceRoute
      • 先调用原生jni代码,调用jni c函数执行traceroute过程。如果发生了异常,再调用java代码执行操作……
      • 然后通过ping命令模拟执行traceroute的过程,比如:ping -c 1 -t 1 www.jianshu.com
      • 如果成功获得trace:IP,则再次发送ping命令获取ping的时间

04.ping工作过程

  • 假定主机A的IP地址是192.168.1.1,主机B的IP地址是192.168.1.2,都在同一子网内,则当你在主机A上运行“Ping 192.168.1.2”后,都发生了些什么呢?
    • 主机A
      • 首先,Ping命令会构建一个固定格式的ICMP请求数据包,然后由ICMP协议将这个数据包连同地址“192.168.1.2”一起交给IP层协议(和ICMP一样,实际上是一组后台运行的进程)
      • IP层协议将以地址“192.168.1.2”作为目的地址,本机IP地址作为源地址,加上一些其他的控制信息,构建一个IP数据包,并在一个映射表中查找出IP地址192.168.1.2所对应的物理地址(也叫MAC地址,熟悉网卡配置的朋友不会陌生,这是数据链路层协议构建数据链路层的传输单元——帧所必需的),一并交给数据链路层。
      • 后者构建一个数据帧,目的地址是IP层传过来的物理地址,源地址则是本机的物理地址,还要附加上一些控制信息,依据以太网的介质访问规则,将它们传送出去。
    • 主机B
      • 主机B收到这个数据帧后,先检查它的目的地址,并和本机的物理地址对比,如符合,则接收;否则丢弃。
      • 接收后检查该数据帧,将IP数据包从帧中提取出来,交给本机的IP层协议。同样,IP层检查后,将有用的信息提取后交给ICMP协议,后者处理后,马上构建一个ICMP应答包,发送给主机A,其过程和主机A发送ICMP请求包到主机B一模一样。
  • 可以参考
    • https://www.cnblogs.com/mgqworks/p/7611314.html

06.ping后返回信息分析

  • 1.Request timed out
    • 这是大家经常碰到的提示信息,很多文章中说这是对方机器置了过滤ICMP数据包,从上面工作过程来看,这是不完全正确的,至少有下几种情况。
    • (1) 对方已关机,或者网络上根本没有这个地址:比如在上图中主机A中PING 192.168.0.7 ,或者主机B关机了,在主机A中PING 192.168.0.5 都会得到超时的信息。
    • (2) 对方与自己不在同一网段内,通过路由也无法找到对方,但有时对方确实是存在的,当然不存在也是返回超时的信息。
    • (3) 对方确实存在,但设置了ICMP数据包过滤(比如防火墙设置)。
      • 怎样知道对方是存在,还是不存在呢,可以用带参数 -a 的Ping命令探测对方,如果能得到对方的NETBIOS(网络基本输入输出系统)名称,则说明对方是存在的,是有防火墙设置,如果得不到,多半是对方不存在或关机,或不在同一网段内。
    • (4) 错误设置IP地址
      • 正常情况下,一台主机应该有一个网卡,一个IP地址,或多个网卡,多个IP地址(这些地址一定要处于不同的IP子网)。但如果一台电脑的“拨号网络适配器”(相当于一块软网卡)的TCP/IP设置中,设置了一个与网卡IP地址处于同一子网的IP地址,这样,在IP层协议看来,这台主机就有两个不同的接口处于同一网段内。当从这台主机Ping其他的机器时,会存在这样的问题:
      • A.主机不知道将数据包发到哪个网络接口,因为有两个网络接口都连接在同一网段。
      • B.主机不知道用哪个地址作为数据包的源地址。因此,从这台主机去Ping其他机器,IP层协议会无法处理,超时后,Ping 就会给出一个“超时无应答”的错误信息提示。但从其他主机Ping这台主机时,请求包从特定的网卡来,ICMP只须简单地将目的、源地址互换,并更改一些标志即可,ICMP应答包能顺利发出,其他主机也就能成功Ping通这台机器了。
  • 2.Destination host Unreachable
    • (1) 对方与自己不在同一网段内,而自己又未设置默认的路由,比如上例中A机中不设定默认的路由,运行Ping 192.168.0.1.4就会出现“Destination host Unreachable”。
    • (2) 网线出了故障。这里要说明一下“destination host unreachable”和 “time out”的区别,如果所经过的路由器的路由表中具有到达目标的路由,而目标因为其他原因不可到达,这时候会出现“time out”,如果路由表中连到达目标的路由都没有,那就会出现“destination host unreachable”。
  • 3.Bad IP address
    • 这个信息表示您可能没有连接到DNS服务器,所以无法解析这个IP地址,也可能是IP地址不存在。
  • 4.Source quench received
    • 这个信息比较特殊,它出现的机率很少。它表示对方或中途的服务器繁忙无法回应。
  • 5.Unknown host——不知名主机
    • 这种出错信息的意思是,该远程主机的名字不能被域名服务器(DNS)转换成IP地址。故障原因可能是域名服务器有故障,或者其名字不正确,或者网络管理员的系统与远程主机之间的通信线路有故障。
  • 6.No answer——无响应
    • 这种故障说明本地系统有一条通向中心主机的路由,但却接收不到它发给该中心主机的任何信息。故障原因可能是下列之一:中心主机没有工作;本地或中心主机网络配置不正确;本地或中心的路由器没有工作;通信线路有故障;中心主机存在路由选择问题。
  • 7.Ping 127.0.0.1:127.0.0.1是本地循环地址
    • 如果本地址无法Ping通,则表明本地机TCP/IP协议不能正常工作。
  • 8.no rout to host
    • 网卡工作不正常
  • 9.transmit failed,error code
    • 10043网卡驱动不正常

07.traceroute使用

  • 有一款充分利用 ICMP 差错报文类型的应用叫做 traceroute(在UNIX、MacOS中是这个命令,而在Windows中对等的命令叫做 tracert )。
  • traceroute 的第一个作用就是故意设置特殊的 TTL,来追踪去往目的地时沿途经过的路由器。
  • traceroute 的参数指向某个目的 IP 地址:traceroute 192.168.1.100这个作用是如何工作的呢?
  • 它的原理就是利用 IP 包的生存期限 从 1 开始按照顺序递增的同时发送 UDP 包,强制接收 ICMP 超时消息的一种方法。
    • 比如,将 TTL 设置 为 1,则遇到第一个路由器,就牺牲了,接着返回 ICMP 差错报文网络包,类型是时间超时。
    • 接下来将 TTL 设置为 2,第一个路由器过了,遇到第二个路由器也牺牲了,也同意返回了 ICMP 差错报文数据包,如此往复,直到到达目的主机。
    • 这样的过程,traceroute 就可以拿到了所有的路由器 IP。当然有的路由器根本就不会返回这个 ICMP,所以对于有的公网地址,是看不到中间经过的路由的。
  • 发送方如何知道发出的 UDP 包是否到达了目的主机呢?
    • traceroute 在发送 UDP 包时,会填入一个不可能的端口号值作为 UDP 目标端口号(大于 3000 )。当目的主机,收到 UDP 包后,会返回 ICMP 差错报文消息,但这个差错报文消息的类型「端口不可达」。
    • 所以,当差错报文类型是端口不可达时,说明发送方发出的 UDP 包到达了目的主机。

参考博客

  • http://www.cppcns.com/ruanjian/android/303246.html
  • Android基础篇_ping实现
    • https://www.cnblogs.com/mgqworks/p/7611314.html
    • https://blog.csdn.net/baidu_30084597/article/details/79603367
  • ping是什么?
    • https://www.jianshu.com/p/d45540c86d2c
  • 博客:https://mp.weixin.qq.com/s/55bbQX2-SUNe6PEI9My5fA
贡献者: yangchong211
上一篇
22.App磁盘沙盒实践
下一篇
24.Gradle构建优化实践