Android 使用ping命令判断当前网络状态

一. 介绍

        ping命令是用来测试和诊断网络连接问题的基本命令,当然我们的终端设备(手机/平板/车机)都可以用这个命令来判断当前网络是否有流量的状态,本篇文章主要介绍Linux的ping命令,因为Android系统也是使用了Linux内核。然后使用ping命令封装一个判断当前网络是否有流量的方法。

二. 作用

使用ping命令作用:

1. 检测网络连接问题:如果我们无法访问某个网站或主机,可以使用ping命令来检测网络连接是否正常。如果ping命令能够成功收到目标主机的回复,说明网络连接正常;如果无法收到回复,可能是网络故障或目标主机不可达。

2. 测量网络延迟:通过ping命令可以测量网络延迟,即从发送ICMP(Internet Control Message Protocol)(Internet控制消息协议)请求到接收到回复所需的时间。可以使用ping命令的-c选项指定发送的ICMP请求次数,然后计算平均延迟时间。较高的延迟可能会导致网络连接缓慢,需要进一步排查网络问题。

3. 检测丢包率:ping命令还可以用于检测网络丢包率,即发送的ICMP请求在传输过程中丢失的比例。可以观察ping命令的输出结果中的丢包率字段,如果丢包率较高,可能是网络拥堵或目标主机负载过高。

三. 使用格式

ping [参数] [主机名或IP地址]

ping命令运行在命令提示符终端,用法为:“ping 参数 目标主机”。其中参数为零到多个,目标主机可以是IP或者域名。

如下图:

ping命令它会持续不断地给目标IP发送ICMP数据报,上面的截图中的每一行代表了一个从ICMP响应的信息,具体包括:

icmp_seq:ICMP 数据包序号,从1开始递增,如果中间不连续代表丢包了。
ttl:生存时间,具体指允许数据包之间通过多少个路由器或跳数,数据包每经过一个路由器,ttl会减1,当ttl归零时,这个数据包的生成周期结束,处理它的路由器会丢弃这个数据包。默认情况下,Linux系统的TTL值为64或255。
time: 这个数据报的响应时间,时间越短,代表响应速度越快。
然后是统计信息,它告诉我们,一共有12个数据报被传递,全被接收,没有数据包丢失。最后一行是:最小/最大/平均响应时间和本机硬件耗费时间。

看下所有的参数:

 ping -help
Usage: ping [-aAbBdDfhLnOqrRUvV64] [-c count] [-i interval] [-I interface]
            [-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
            [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
            [-w deadline] [-W timeout] [hop1 ...] destination
Usage: ping -6 [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
             [-l preload] [-m mark] [-M pmtudisc_option]
             [-N nodeinfo_option] [-p pattern] [-Q tclass] [-s packetsize]
             [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline]
             [-W timeout] destination

好了,到这里,我们来介绍一下它的参数:

参数详解
-aAudible ping. 
-A自适应ping,根据ping包往返时间确定ping的速度;
-c countping指定次数后停止ping;
-i interval设定间隔几秒发送一个ping包,默认一秒ping一次;
-I interface指定网卡接口、或指定的本机地址送出数据包;
-l preload设置在送出要求信息之前,先行发出的数据包;
-q不显示任何传送封包的信息,只显示最后的结果
-Q tos设置Qos(Quality of Service),它是ICMP数据报相关位;可以是十进制或十六进制数,详见rfc1349和rfc2474文档;
-R记录ping的路由过程(IPv4 only);
注意:由于IP头的限制,最多只能记录9个路由,其他会被忽略;
-s packetsize指定每次ping发送的数据字节数,默认为“56字节”+“28字节”的ICMP头,一共是84字节;
包头+内容不能大于65535,所以最大值为65507(linux:65507, windows:65500);
-t ttl设置TTL(Time To Live)为指定的值。该字段指定IP包被路由器丢弃之前允许通过的最大网段数;
-T timestamp_option

设置IP timestamp选项,可以是下面的任何一个:
'tsonly' (only timestamps)
'tsandaddr' (timestamps and addresses)
'tsprespec host1 [host2 [host3]]' (timestamp prespecified hops).

-v使ping处于verbose方式,它要ping命令除了打印ECHO-RESPONSE数据包之外,还打印其它所有返回的ICMP数据包;
-W timeout以毫秒为单位设置ping的超时时间;
-w deadlinedeadline;  单位 秒

其实常用的就是如下几个:

ping常用命令选项:

-c count:指定发送的ICMP请求次数,默认为无限次。

-i interval:指定发送ICMP请求的时间间隔,默认为1秒。

-s packetsize:指定发送的ICMP请求的数据包大小,默认为56字节。

-W timeout:指定等待ICMP回复的超时时间,默认为10秒。

-w 10   : 最长超时时间为10秒

四. 实际使用

使用ping命令访问阿里公共DNS,来判断当前网络是否有流量,间接的判断当前网络是否可用,目前国内公共的DNS有:

服务商公共DNS服务器IP公共DNS服务器IP
阿里DNS223.5.5.5223.6.6.6
114公共DNS114.114.114.114
百度DNS180.76.76.76
腾讯DNS119.29.29.29
电信101.226.4.6
联通123.125.81.6
移动101.226.4.6
谷歌8.8.8.88.8.4.4
IBM Quad9DNS9.9.9.9
微软DNS4.2.2.1
华为DNS139.9.23.90122.112.208.1
114.115.192.11116.205.5.1

代码如下:

 public boolean isNetworkHasTraffic() {
        Runtime runtime = Runtime.getRuntime();
        java.lang.Process ipProcess = null;
        try {
            ipProcess = runtime.exec("ping -c 4 -i 0.2 -w 1 223.5.5.5");
            InputStream inputStrem = ipProcess.getInputStream();
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStrem));
            StringBuffer stringBuffer = new StringBuffer();
            String content = "";

            while ((content = in.readLine()) != null) {
                stringBuffer.append(content);
            }

            int exitValue = ipProcess.waitFor();
            Log.i(TAG, "return result after executing the ping command: " + exitValue);

            if (exitValue == 0) {
                //网络正常且有流量
                return true;
            } else if (exitValue == 1) {
                if (stringBuffer.indexOf("100% packet loss") != -1) {
                    //状态值返回1 网络丢包严重,判断为网络未连接
                    return false;
                } else {
                    return true;
                }
            } else if (exitValue == 2) {
                // 状态值返回2  网络未连接不可用
                return false;
            } else {
                // 其他异常场景
                return false;
            }
        } catch(IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (ipProcess != null) {
                ipProcess.destroy();
            }
            runtime.gc();
        }
        return false;
    }

该方法中的ping 命令:

ping -c 4 -i 0.2 -w 1 223.5.5.5

发送4次数据, 每次间隔200毫秒,deadline 为1秒执行完成   

233.5.5.5 为阿里DNS

ping -c 4 -i 0.2 -w 1 223.5.5.5
PING 223.5.5.5 (223.5.5.5) 56(84) bytes of data.
64 bytes from 223.5.5.5: icmp_seq=1 ttl=114 time=87.7 ms
64 bytes from 223.5.5.5: icmp_seq=2 ttl=114 time=71.0 ms
64 bytes from 223.5.5.5: icmp_seq=3 ttl=114 time=72.2 ms
64 bytes from 223.5.5.5: icmp_seq=4 ttl=114 time=71.0 ms

--- 223.5.5.5 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 601ms
rtt min/avg/max/mdev = 71.007/75.506/87.732/7.084 ms

返回值是通过调用 Process.waitFor() 方法,根据实际测试用例场景

1. 打开和关闭 手机流量开关  当正常上网时,返回值为0   关闭流量开关: 返回值2 

2. 连接上有流量的Wifi热点,正常上网时,返回值为0

3. 连接上没有流量的Wifi热点, 无法上网,返回值为1 ,此时丢包率是100%

五. 注意事项

java中 Process的waitFor() 方法说明

JDK帮助文档上这么说:如有必要,一直要等到由该 Process 对象表示的进程已经终止。如果已终止该子进程,此方法立即返回。但是直接调用这个方法会导致当前线程阻塞,直到退出子进程。

也就是说: 此方法不建议使用在主线程中,因为ping网络的过程是一个耗时操作,Process的waitFor()方法会阻塞当前线程 直接导致结果: 阻塞UI线程。

        经过实际测试,确实会影响主线程,验证过程: 我把这个方法写在生命周期onStart()方法中,onResume() 就会延时1秒执行。那么UI界面也会延时1秒显示,这对用户追求系统流畅角度来看,这当然是不允许的。

        当然waitFor()方法除了 0/1/2 还有很多返回值,详细见:Process.waitFor()方法的返回值

 

六. 方法封装

在第5小节,我们已经说明此方法不建议使用在主线程中,下面是封装的方法和使用代码

使用方法一:

new Thread(new Runnable() {
            @Override
            public void run() {
               boolean isAvalible =  isNetworkHasTraffic();
               //根据这个判断条件去处理对应的业务逻辑
               if (isAvalible) { 
                   Log.d(TAG, " 网络正常 ");
               } else {
                   Log.d(TAG, " 当前网络不可用 ");
               }
            }
        }).start();

        

使用方法二:使用AsyncTask,把耗时操作放在doInBackground方法中,在子线程中做ping操作,当结果返回时,在onPostExecute主线程中更新状态。

/*
     Params:决定了执行excute()方法时传入的参数类型,excute()方法传入的参数会传入到方法doInBackground(),所以同时也决定了doInBackground()方法内的参数类型。
     Progress:任务执行时,返回进度值的类型,即onProgressUpdate()方法内的参数类型。
     Result:任务完成后,返回的结果的类型,即doInBackground()方法的返回类型,doInBackground()方法的返回结果传入onPostExecute()方法作为参数,所以同时也决定了onPostExecute()方法的参数类型。
    *
    * */

    private abstract class getNetworkStatusTask extends AsyncTask<Void,Void,Boolean> {
        @Override
        protected Boolean doInBackground(Void... voids) {
           return isNetworkHasTraffic();
        }

        //定义为抽象方法,在子类复写
        @Override
        protected abstract void onPostExecute(Boolean aBoolean);
    }


//调用代码
   new getNetworkStatusTask(){
                @Override
                protected void onPostExecute(Boolean hastraffic) {
                    //根据判断条件处理业务逻辑代码
                    if (hastraffic) {
                        Log.d(TAG, "====网络正常=====");
                    } else {
                        Log.d(TAG, "====网络不可用=====");
                    }
                }
            }.execute();

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【面经】操作系统/Linux

1、计算机的五大单元 电脑的五大单元包括&#xff1a;输入单元、输出单元、控制单元、算数逻辑单元、存储单元五大部分。其中CPU占有控制、算术逻辑单元&#xff0c;存储单元又包含内存与辅助内存&#xff1b; 2、什么是操作系统 操作系统&#xff1a;负责管理协调我们计算机…

汽车车灯用肖特基二极管,选什么型号好?

肖特基二极管种类繁多&#xff0c;有低压降肖特基二极管、通用型肖特基二极管、快速恢复型肖特基二极管、高功率肖特基二极管、汽车级肖特基二极管等等&#xff0c;其中低压降肖特基二极管和汽车级肖特基二极管是二极管厂家东沃电子的核心优势产品。关于东沃电子推出的低压降肖…

Android 接入MQTT服务器

加入MQTT库 加入库可以直接下载对应的jar包&#xff0c;也可以在build.gradle里导入&#xff0c;然后加载进入。 这里直接在build.gradle加库 dependencies {implementation(libs.appcompat)implementation(libs.material)implementation(libs.activity)implementation(libs…

【k8s】:深入理解k8s中的亲和性(Affinity)及其在集群调度中的应用

【k8s】&#xff1a;深入理解k8s中的亲和性&#xff08;Affinity&#xff09;及其在集群调度中的应用 1、什么是亲和性&#xff1f;2、节点亲和性&#xff08;Node Affinity&#xff09;2.1 硬性节点亲和性规则&#xff08;required&#xff09;2.2 软性节点亲和性规则&#xf…

如何制作二维码电子画册?轻松入门,快速上手!

在当今数字化时代&#xff0c;二维码电子画册成为了企业推广和信息传递的重要工具之一。相比传统纸质画册&#xff0c;二维码电子画册不仅环保节能&#xff0c;而且可以通过扫描二维码轻松获取更多详细信息&#xff0c;为用户提供了更加便捷的阅读体验。 今天就教大家如何制作二…

【Java开发指南 | 第三篇】Java 空行、强制类型转换及基本数据类型

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 Java 空行强制类型转换Java 基本数据类型内置数据类型引用类型 Java 空行 空白行或者有注释的行&#xff0c;Java 编译器都会忽略掉。 强制类型转换 当需要将一个数据类型转换为另一个数据类型时&#xff0c…

浅尝 express + ORM框架 prisma 的结合

一、prisma起步 安装&#xff1a; npm i prisma -g查看初始化帮助信息&#xff1a; prisma init -h查看初始化帮助信息结果&#xff1a; Set up a new Prisma projectUsage$ prisma init [options] Options-h, --help Display this help message --datasource-provider …

Intewell-Hyper II_V2.1.1_工业实时操作系统软件版本发布

Intewell-Hyper II_V2.1.1_工业实时操作系统软件版本发布 Intewell-Hyper II_V2.1.1 版本号&#xff1a;V2.1.1 版本特点 新增V1.3.2分支上SHV构型合并及问题回归 版本或修改说明 增加功能&#xff1a; 1.V1.3.2分支上SHV构型合并及问题回归 2.适配NewPre3102和NewPre3101…

node+vue3的websocket前后端消息推送

nodevue3的websocket前后端消息推送 前期写web项目时&#xff0c;前端获取数据的方式一般是向后端发起数据请求&#xff0c;然后后端向前端发送数据&#xff0c;然后对数据进行渲染&#xff0c;这是最常规的一种数据通讯方式&#xff0c;适用于绝大部分前后端分离的项目 实际…

java的ConcurrentHashMap深入理解

概要 怎么保证线程安全&#xff1a; 在初始化数组时用了cas操作&#xff0c;sizectl作为占位标志(U.compareAndSwapInt(this, SIZECTL, sc, -1&#xff09;&#xff1b;获取数组中的元素是否已经有了&#xff0c;用Volatile修饰数组&#xff08;保证可见性&#xff09;&#…

边缘计算网关有哪些优势?-天拓四方

随着信息化、智能化浪潮的持续推进&#xff0c;计算技术正以前所未有的速度发展&#xff0c;而边缘计算网关作为其中的重要一环&#xff0c;以其独特的优势正在逐步改变我们的生活方式和工作模式。本文将详细解析边缘计算网关的优势。 首先&#xff0c;边缘计算网关具有显著的…

【好书推荐6】《Excel函数与公式应用大全for Excel 365 Excel 2021》

【好书推荐6】《Excel函数与公式应用大全for Excel 365 & Excel 2021》 写在最前面《Excel函数与公式应用大全for Excel 365 & Excel 2021》关键点内容简介作者简介前言/序言目录 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&…

Linux之命令行参数的原理以及实现,环境变量限时增加删除和永久增加删除以及代码获取环境变量

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 算法 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 一.命令行参数 1.1main函数参数 在我们学习c语言时我们的main函数…

Vue - 5( 16000 字 Vue2 入门级教程)

一&#xff1a;Vue 初阶 1.1 组件自定义事件 在 Vue 中&#xff0c;组件间通过自定义事件进行通信是一种常见的模式。自定义事件允许子组件向父组件发送消息&#xff0c;也可以在组件内部进行事件的绑定、触发和解绑。让我们详细讲解这些知识点。 1.1.1 组件自定义事件 在 …

最前沿・量子退火建模方法(2) : Domain wall encoding讲解和python实现

前言 上篇讲的subQUBO属于方法论&#xff0c;这次讲个通过编码量子比特的方式&#xff0c;同样的约束条件&#xff0c;不同的编码&#xff0c;所需的量子比特数是不同的。有的编码方式&#xff0c;很节省量子比特。比如&#xff0c;这次要讲的Domain wall encoding。 一、Doma…

一文总结:Python的封装、继承和多态

整个程序员的生涯&#xff0c;最重要的一个知识根基就是面向对象的理解和掌握深度。如果你意识到了面向对象开发思想的重要性&#xff0c;请仔细学习这篇文章。 希望对你有帮助&#xff01; 这篇详细地解释封装、继承和多态&#xff0c;并在最后提供一个综合示例来总结这三个…

PyQt介绍——弹框介绍和使用

PyQt介绍——弹框介绍和使用 一、QMessageBox QMessageBox是一种通用的弹出式对话框&#xff0c;用于显示消息&#xff0c;允许用户通过单击不同的标准按钮对消息进行反馈 QMessageBox类提供了许多常用的弹出式对话框&#xff0c;如提示、警告、错误、询问、关于等对话框。这…

Hyper-v 新建 Windows 虚拟机卡在“Press any key to boot from CD or DVD...,无法按下任何按键

Hyper-v 新建 Windows 虚拟机卡在“Press any key to boot from CD or DVD…&#xff0c;无法按下任何按键 在显示这个界面之后点击启动&#xff0c;之后立刻狂按F2&#xff0c; 然后就能进去了

​代码混淆的原理是什么?常见代码混淆方法介绍

本文主要想你介绍代码混淆的原理&#xff0c;常见代码混淆方法&#xff0c;欢迎查阅~ 移动应用代码安全非常重要&#xff0c;代码逆向会导致代码逻辑被获取&#xff0c;进一步导致控制流被hook&#xff0c;安全防线被破&#xff0c;给APP安全带来巨大风险&#xff0c;因此开发者…

淘宝扭蛋机小程序:扭转购物新风尚,开启惊喜连连之旅

随着移动互联网的飞速发展&#xff0c;淘宝作为国内领先的电商平台&#xff0c;始终致力于为用户带来更加新颖、有趣的购物体验。如今&#xff0c;我们隆重推出淘宝扭蛋机小程序&#xff0c;将传统扭蛋机的乐趣与电商购物的便捷完美结合&#xff0c;为用户带来前所未有的惊喜与…