java检测服务器之间网络状况及丢包率

问题
服务器因为防火墙的原因,或者为了安全禁止了ping服务,导致无法ping通,会让我们误判断两个服务器之间网络不通,但是服务器却可以远程访问,是正常连通状态,编写程序判断两个服务器之间网络状况。
思路
1、先判断网络是否可以连通;
2、可以连通在程序中使用ping命令获取网络状况和丢包率;
3、无法连通,使用ping命令先获取网络丢包率,再通过对外开放的端口使用TCP三次握手判断是否可连接;
4、UDP无法判断,UDP是无连接状态,发送出去就不会考虑对方是否接收;
解决
准备:确保被检测的服务器是开启状态,并将需要对外开放的端口放开。
实现代码
获取网络状态

 /**
     * 获取网络状态
     * @param host
     * @param timeout
     * @return
     */
    private static boolean isHostReachable(String host,Integer timeout){
        try {
            return InetAddress.getByName(host).isReachable(timeout);
        } catch (IOException e) {
            logger.error("判断网络状态异常" + e.getMessage());
            e.printStackTrace();
        }
        return false;
    }

使用ping的方式获取丢包率,windows和Linux系统ping命令获取的结果不一样,需要分开解析返回的字符串

 /**
     * 通过ip获取信息,loss:丢包率,delay:延时
     * @param cmd
     * @return
     */
    private static Map<String,String> getNetworkStatusByPing(String os,String cmd){
        Map<String,String> networkMap = new HashMap<>(3);
        //获取当前进程运行对象
        Runtime runtime = Runtime.getRuntime();
        Process process = null;
        String line = null;
        InputStream inputStream = null;
        InputStreamReader isReader = null;
        BufferedReader reader = null;

        String loss = "";//丢包率
        String delay = "";//延时
        try {
            process = runtime.exec(cmd);
            inputStream = process.getInputStream();//实例化输入流
            isReader = new InputStreamReader(inputStream,"GB2312");
            reader = new BufferedReader(isReader);
            StringBuffer buffer = new StringBuffer();
            if (os.contains("win") || os.contains("Win")|| os.contains("WIN")){//Windows系统执行结果解析
                while ((line = reader.readLine()) != null){
                    //丢包率
                    if (line.contains("%")){
                        loss = line.substring(line.lastIndexOf("=") + 1 ,line.indexOf("%") + 1);
                        if (loss.contains("(")){
                            loss = loss.substring(loss.indexOf("(") + 1).trim();
                        }
                        System.out.println(loss);
                    }
                    //网络延时
                    if ((line.contains(",") || line.contains(",")) && line.contains("=") && line.contains("ms")){
                        delay = line.substring(line.lastIndexOf("=") + 1 ,line.lastIndexOf("ms") + 2).trim();
                        System.out.println(delay);
                    }
                    buffer.append(line + "\n");
                }
            }else{//Linux系统执行结果解析
                while ((line = reader.readLine()) != null){
                    //丢包率
                    if (line.contains("%")){
                        String[] msg = null;
                        if (line.contains(",")){
                            msg = line.split(",");
                        }else if (line.contains(",")){
                            msg = line.split(",");
                        }
                        if (msg.length > 0) {
                            loss = msg[2].substring(0, msg[2].indexOf("%") + 1).trim();
                            System.out.println(loss);
                        }
                    }
                    //网络延时
                    if (line.contains("/")){
                        String[] msg = line.split("=");
                        String[] names = msg[0].split("/");
                        String[] values = msg[1].split("/");
                        for (int i = 0;i < names.length;i++){
                            String str = names[i];
                            if ("avg".equalsIgnoreCase(str)){
                                delay = values[i];
                                break;
                            }
                        }
                        System.out.println(delay);
                    }
                    buffer.append(line + "\n");
                }
            }

            if (StringUtils.isNotEmpty(loss)){
                networkMap.put("loss",loss);
            }else {
                networkMap.put("loss","0%");
            }
            if (StringUtils.isNotEmpty(delay)){
                networkMap.put("delay",delay);
            }else {
                networkMap.put("delay","99999ms");
                networkMap.put("status","-1");//无法ping通
            }
            System.out.println(buffer.toString());

            inputStream.close();
            isReader.close();
            reader.close();
//            runtime.exit(1);
        } catch (IOException e) {
            logger.error("通过ping方式获取网络信息异常:" + e.getMessage());
            e.printStackTrace();
//            runtime.exit(1);
        }
        return networkMap;
    }

判断开发端口网络状况

 /**
     * 判断指定端口网络状态
     * @param localAddress  源地址
     * @param remoteAddress 目标地址
     * @param port          端口
     * @param timeout       超时时间
     * @return
     */
    private static boolean isRealchable(InetAddress localAddress,InetAddress remoteAddress,int port,int timeout){
        boolean realchable = false;
        Socket socket = null;
        try {
            socket = new Socket();
            //端口为0标识在本地挑选一个可用端口进行连接
            SocketAddress socketAddress = new InetSocketAddress(localAddress,0);
            socket.bind(socketAddress);
            InetSocketAddress endpointSocketAddress = new InetSocketAddress(remoteAddress,port);
            socket.connect(endpointSocketAddress,timeout);
            System.out.println("Socket连接建立成功");
            realchable = true;
        } catch (IOException e) {
            logger.info("Socket连接失败,localAddress:" + localAddress
                    + ",remoteAddress:" + remoteAddress + ",port:" + port) ;
            System.out.println("Socket连接失败,localAddress:" + localAddress
                    + ",remoteAddress:" + remoteAddress + ",port:" + port );
        }finally {
            if (socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return realchable;
    }

    /**
     * 判断指定端口网络状况
     * @param remoteAddress 目标地址
     * @param port          端口
     */
    public static boolean getNetworkByPort(InetAddress remoteAddress,int port){
        boolean netStatus = false;

        Enumeration<NetworkInterface> netInterfaces;
        try {
            netInterfaces = NetworkInterface.getNetworkInterfaces();
            while (netInterfaces.hasMoreElements()){
                NetworkInterface ni = netInterfaces.nextElement();
                Enumeration<InetAddress> localAddress = ni.getInetAddresses();
                while (localAddress.hasMoreElements()){
                    InetAddress local = localAddress.nextElement();
                    if (isRealchable(local,remoteAddress,port,3000)){
                        netStatus = true;
                        break;
                    }
                }
            }
        } catch (SocketException e) {
            logger.error("获取本地ip与目标地址端口通信失败:" + e.getMessage());
            e.printStackTrace();
        }
        System.out.println(netStatus);
       return netStatus;
    }

办法很蠢,路过有获取网络丢包率好办法的请告知一下!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值