android ping 网络延迟
16lz
2021-01-23
针对 android 检查服务器和本地网络延迟
/** * Created by Patrick on 2017/7/31. * 网络诊断服务 通过对制定域名进行ping *//* 创建监听 this.mLDNetPingService = new NetPingManager(getApplicationContext(), "www.baidu.com", new NetPingManager.IOnNetPingListener() { @Override public void ontDelay(String log) { Log.e("tag", "log-->" + log); } }); //开始监听 if (null != mLDNetPingService) this.mLDNetPingService.getDelay(); //释放 if (null != mLDNetPingService) this.mLDNetPingService.release(); */public class NetPingManager { private String mDomain; // 接口域名 private InetAddress[] mAddress; private List mAddressIpList; private IOnNetPingListener mIOnNetPingListener; // 将监控日志上报到前段页面 private HandlerThread mHandlerThread; private static int DELAY_TIME = 1000; private ConnectivityManager manager; private final Handler mHandleMessage; /** * 延迟 */ public void setDuration(int delay) { DELAY_TIME = delay; } /** * 初始化网络诊断服务 */ public NetPingManager(Context context, String domain, IOnNetPingListener theListener) { this.mDomain = domain; this.mIOnNetPingListener = theListener; this.mAddressIpList = new ArrayList<>(); if (null != context) this.manager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); this.mHandlerThread = new HandlerThread("ping"); this.mHandlerThread.start(); this.mHandleMessage = new Handler(mHandlerThread.getLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0: //每次请求清空上传集合 if (null != mAddressIpList) mAddressIpList.clear(); startNetDiagnosis(); if (null != mHandlerThread) mHandleMessage.sendEmptyMessageDelayed(0, DELAY_TIME); break; } } }; } public void getDelay() { if (null != this.mHandleMessage) { this.mHandleMessage.sendEmptyMessage(0); } } public void release() { synchronized (NetPingManager.class) { if (null != this.manager) this.manager = null; if (null != this.mHandleMessage) { this.mHandleMessage.removeMessages(0); } if (null != mHandlerThread) { Looper looper = this.mHandlerThread.getLooper(); if (looper != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { looper.quitSafely(); } else { looper.quit(); } } } this.mHandlerThread = null; this.mIOnNetPingListener = null; if (null != mAddressIpList) mAddressIpList.clear(); this.mAddressIpList = null; this.manager = null; } } /** * 监控网络诊断的跟踪信息 */ public interface IOnNetPingListener { void ontDelay(long log); void onError(); } /** * 开始诊断网络 */ private void startNetDiagnosis() { if (!TextUtils.isEmpty(this.mDomain)) { // 网络状态 if (isNetworkConnected()) { parseDomain(this.mDomain);// 域名解析 // TCP三次握手时间测试 execUseJava(); } else { if (null != mIOnNetPingListener) mIOnNetPingListener.onError(); Log.e("tag", "当前主机未联网,请检查网络!"); } } } /** * 使用java执行connected */ private boolean execUseJava() { if (mAddress != null && mAddressIpList != null) { int len = mAddress.length; if (len > 1) { execIP(mAddress[0], mAddressIpList.get(0)); } } return false; } private static final int PORT = 80; private static final int CONN_TIMES = 4; // 设置每次连接的timeout时间 private int TIME_OUT = 6000; private final long[] RttTimes = new long[CONN_TIMES];// 用于存储三次测试中每次的RTT值 /** * 返回某个IP进行5次connect的最终结果 */ private boolean execIP(InetAddress inetAddress, String ip) { boolean isConnected = true; InetSocketAddress socketAddress; if (inetAddress != null && ip != null) { socketAddress = new InetSocketAddress(inetAddress, PORT); int flag = 0; for (int i = 0; i < CONN_TIMES; i++) { execSocket(socketAddress, i); if (RttTimes[i] == -1) {// 一旦发生timeOut,则尝试加长连接时间 TIME_OUT += 4000; if (i > 0 && RttTimes[i - 1] == -1) {// 连续两次连接超时,停止后续测试 flag = -1; break; } } else if (RttTimes[i] == -2) { if (i > 0 && RttTimes[i - 1] == -2) {// 连续两次出现IO异常,停止后续测试 flag = -2; break; } } } long time = 0; int count = 0; if (flag == -1) { isConnected = false; } else if (flag == -2) { isConnected = false; } else { for (int i = 0; i < CONN_TIMES; i++) { if (RttTimes[i] > 0) { time += RttTimes[i]; count++; } } if (count > 0) { if (mIOnNetPingListener != null) mIOnNetPingListener.ontDelay(time / count); } } } else { isConnected = false; } return isConnected; } /** * 针对某个IP第index次connect */ private void execSocket(InetSocketAddress socketAddress, int index) { long start; long end; Socket mSocket = new Socket(); try { start = System.currentTimeMillis(); mSocket.connect(socketAddress, TIME_OUT); end = System.currentTimeMillis(); RttTimes[index] = end - start; } catch (SocketTimeoutException e) { RttTimes[index] = -1;// 作为TIMEOUT标识 e.printStackTrace(); } catch (IOException e) { RttTimes[index] = -2;// 作为IO异常标识 e.printStackTrace(); } finally { if (mSocket != null) { try { mSocket.close(); } catch (IOException io) { io.printStackTrace(); } } } } /** * 判断网络是否连接 */ private Boolean isNetworkConnected() { if (manager == null) return false; NetworkInfo networkinfo = manager.getActiveNetworkInfo(); return !(networkinfo == null || !networkinfo.isAvailable()); } /** * 域名解析 */ private boolean parseDomain(String domain) { boolean flag = false; Map map = getDomainIp(domain); String useTime = (String) map.get("useTime"); mAddress = (InetAddress[]) map.get("remoteInet"); if (mAddress != null) {// 解析正确 mAddressIpList.add(mAddress[0].getHostAddress()); flag = true; } else {// 解析不到,判断第一次解析耗时,如果大于10s进行第二次解析 if (Integer.parseInt(useTime) > 10000) { map = getDomainIp(domain); mAddress = (InetAddress[]) map.get("remoteInet"); if (mAddress != null) { mAddressIpList.add(mAddress[0].getHostAddress()); flag = true; } } } return flag; } /** * 解析IP */ private Map getDomainIp(String domain) { Map map = new HashMap<>(); long start = 0; long end; String time = null; InetAddress[] remoteInet = null; try { start = System.currentTimeMillis(); remoteInet = InetAddress.getAllByName(domain); if (remoteInet != null) { end = System.currentTimeMillis(); time = (end - start) + ""; } } catch (UnknownHostException e) { end = System.currentTimeMillis(); time = (end - start) + ""; remoteInet = null; e.printStackTrace(); } finally { map.put("remoteInet", remoteInet); map.put("useTime", time); } return map; }}
更多相关文章
- Android实现自定义的 时间日期 控件
- 关于Android 如何配置测试类
- android studio更新提示网络连接失败的解决办法
- android 下测试网络的丢包率和延迟 的代码
- traceview进行Android性能测试
- android粗略获得程序运行时间的方法
- android 开发 时间选择器TimePicker的使用
- Android之网络请求7————OkHttp源码4:网络操作