`
xiaozhonghua
  • 浏览: 253795 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
阅读更多

JavaEye上不少朋友是做网管系统的。一个典型的网络管理系统,需要具备FCAPS几个标准模块,而网络的自动发现和拓扑展示是核心之一。很多人不喜欢Java的Swing,而本文就用一个很小很小的例子,来模拟一个小小的网络管理程序,希望能给大家一点启发。虽然很小,它却可以完成一个简单的局域网自动发现搜索、多线程、ICMP和SNMP的ping、节点的生成、拓扑的展示、自动布局等功能。继续改巴改巴也许还有点使用价值也未可知。

 

如果不喜欢研究代码,就当它是一个趣味程序吧!你可以在公司的网络里面搜索一把,把同事的机器都挖出来,看看你们公司的网络结构是怎样的;如果喜欢研究代码,可以看看相关SNMP、多线程和拓扑图展示的部分,虽然很简单,就当看肥皂剧消遣了。

 

Ping和SNMP PING

这个程序的自动发现比较简单,就是对所在的网段进行便利搜索。首先,获得本机的网址以及所在的网段。例如,如果本机的地址是192.168.1.122,那么所在的网段自然就是192.168.1.0。然后,将这个网段中所有可能存在的IP地址进行拆分,并通过多线程进行任务分配,一个一个的Ping。

 

 

    public static boolean ping(String ip) {
        try {
            InetAddress ipaddress = InetAddress.getByName(ip);
            return ipaddress.isReachable(2000);
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }
 

 

用Java来Ping机器,有两个做法。一个是传统的调用命令行执行Ping命令的做法。这种做法的好处是速度快,比较可靠。缺点是,不同的操作系统,甚至Windows的不同版本,其执行和返回结果格式都可能不同,造成跨平台的不便以及代码的啰嗦。第二个方法自然就是使用大家都熟知的Java 5提供的InetAddress的isReachable方法。这个方法本来应当很好,可是在实际使用中就会发现,它不大灵光。超时时间设置短了吧,就ping不through;长了把,又贼慢。网上不少人都反映和抱怨这个问题。仔细研究这个isReachable,会发现更多的问题。1、它不是线程安全的。也就是说,为了提高速度而使用多线程进行多节点并行ping,会导致不安全的返回结果。这个问题挺致命。2、这个函数并非使用ICMP的ping,而是仅仅用TCP连一下7号端口而已:

 

 写道
InetAddress.isReachable() doesn't use ICMP, it just tries to open TCP port 7 at the target. You can use ICMP in Java with the JPCAP library if you can find it, but you can't multithread it for reasons which are discussed above - basically, ICMP is not thread-safe

 

又慢又线程不安全就比较不爽了。还可以使用上面提到的JPCAP这个库来完成。这个库的地址是:

http://netresearch.ics.uci.edu/kfujii/jpcap/doc/

 

不管怎么说,一个小小的ping还是挺麻烦。不过本例子由于仅仅是示例小程序,还是使用了isReachable方法,简化代码。

 

在ping通一个机器后,接下来再使用SNMP进行ping。做过SNMP网管的朋友知道,所谓SNMP Ping其实就是用SNMP去get一个非常基本的OID看对方有无反应。如果能够返回数据,说明这是一个SNMP节点,可以通过SNMP配合MIB库去获取更多的业务数据。例如磁盘、CPU、内存、端口力量等等基本的信息,都有相关的SNMP MIB进行定义。

 

这个例子使用了Westhawk's SNMP stack这个SNMP协议栈,一个轻量的、Java的、开源的、免费的SNMP协议栈,实现了SNMPv1、SNMPv2c以及SNMPv3 (包括MD5和SHA1以及DES, AES加密算法)。地址在这里:

http://snmp.westhawk.co.uk/

 

使用Westhawk's SNMP做一个简单的get操作如下:

 

 

            SnmpContextv2c context = new SnmpContextv2c(ip, 161);
            context.setCommunity("public");

            BlockPdu pdu = new BlockPdu(context);
            pdu.setRetryIntervals(new int[]{1000});
            String sysUpTime = "1.3.6.1.2.1.1.3.0";
            pdu.addOid(sysUpTime);
            Object result = pdu.getResponseVariable();

代码中用v2c,并假设community是public,超时时间1秒。获取sysUpTime也就是设备启动时间。如果有返回,认为节点存在且SNMP协议已启动。

 

 

本例子就ping这么多。如果做一个真正的综合设备网管,可以先获得设备的标识OID,判断其设备厂商和型号,然后加载对应设备支持的MIB进行复杂的监控。

 

多线程任务

由于一个网段需要ping的地址很多,一个线程会很慢。所以这个例子中使用很多线程并发进行。例如192.168.1.*里面有254个可能节点,就用10个线程去分头ping然后汇总。这个让人想起网络蚂蚁。于是就做了一个类似网络蚂蚁的界面。


其中,每个球是一个可能存在的节点地址。每个红色的球是一个线程正在ping这个节点。灰色的球是已经被ping过证明不存在或无法ping通的地址。绿色球是已经ping通,存在的节点。

 

通过调节线程的数量,可以掌握网络发现的速度。一般这254个节点,可以在30秒到60秒内完成。

 

拓扑呈现

拓扑呈现用TWaver就行了。每次发现一个存在的节点,往Network中new一个Node,设置一个图标即可。同时,在网段节点(一个云形图标的节点)和计算机节点创建一个连线。

 

同时,把拓扑图network组件的弹簧布局打开。这样,每次节点加入,都会像弹簧一样被自动布局到合适的位置,比较动感、有视觉效果。

 

            network.getSpringLayouter().setMovableFilter(new MovableFilter() {

                public boolean isMovable(Element element) {
                    return element != centerNode;
                }
            });
            network.getSpringLayouter().start();
            network.getSpringLayouter().setLinkRepulsionFactor(2);
 

 

 

另外,一旦ping通,我们在节点上就显示一个windows图标;如果snmp能ping通,再显示一个齿轮的图标。显示效果如下:


显示图标的代码很简单:

 

 

        ResizableNode node = new ResizableNode(ipaddress);
        node.setImage("/demo/main/snmp/images/node.png");
        node.addAttachment("winxp");
        node.putAttachmentPosition(TWaverConst.POSITION_TOPLEFT);
        if (snmpPingOK) {
            node.addAttachment("snmp");
        }
 

 

此外,可以通过windows的“net view hostname”的命令来查看一个机器的共享信息。我们做一个右键菜单,将执行命令结果显示出来:

 


显示结果如下:

 


 

结果显示,这台test计算机上有“move”、“SharedDocs”两个共享目录,以及三个共享打印机。实现的代码如下:

 

 

import java.io.*;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import twaver.*;
import twaver.network.*;

public class SnmpPopupMenuFactory implements PopupMenuFactory {

    private TNetwork network = null;

    public SnmpPopupMenuFactory(TNetwork network) {
        this.network = network;
    }

    public JPopupMenu getPopupMenu(DataBoxSelectionModel dataBoxSelectionModel, Point point) {
        if (network.getDataBox().getSelectionModel().size() == 1) {
            Element element = network.getDataBox().getSelectionModel().lastElement();
            if (element instanceof ResizableNode) {
                final Node node = (Node) element;

                JPopupMenu menu = new JPopupMenu();
                JMenuItem item = new JMenuItem("View this computer");
                item.addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        String result = executeCommand("net view \\\\" + node.getName());
                        if (result != null && !result.trim().isEmpty()) {
                            JOptionPane.showMessageDialog(network, result);
                        } else {
                            JOptionPane.showMessageDialog(network, "No information available.");
                        }
                    }
                });
                menu.add(item);

                return menu;
            }
        }
        return null;
    }

    private static String executeCommand(String command) {
        try {
            Process p = Runtime.getRuntime().exec(command);
            InputStreamReader ir = new InputStreamReader(p.getInputStream());
            LineNumberReader input = new LineNumberReader(ir);

            String result = null;
            String line = input.readLine();
            while (line != null) {
                if (result == null) {
                    result = line;
                } else {
                    if (!line.trim().equalsIgnoreCase("")) {
                        result = result + "\n" + line.trim();
                    }
                }
                line = input.readLine();
            }
            return result;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    //可以用这两行代码来测试test机器的返回结果。
    public static void main(String[] args) {
        String result = executeCommand("net view \\\\test");
        System.out.println(result);
    }
}
 

 

 

链路探测与告警

在所有的节点被探索结束并放入界面后,我们可以起一个线程,周期性对每个节点进行ping。一旦无法ping通,生成告警,显示在拓扑图中。

 

 

Thread linkCheckThread = new Thread() {

            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(3000);
                        if (!network.getDataBox().isEmpty()) {
                            Collection elements = network.getDataBox().getAllElements();
                            Iterator it = elements.iterator();
                            while (it.hasNext()) {
                                final Element element = (Element) it.next();
                                if (element instanceof ResizableNode) {
                                    final String ipaddress = element.getID().toString();
                                    final boolean pingOK = ping(ipaddress);

                                    SwingUtilities.invokeLater(new Runnable() {

                                        public void run() {
                                            Alarm alarm = new Alarm();
                                            if (!pingOK) {
                                                alarm.setAlarmSeverity(AlarmSeverity.CRITICAL);
                                            } else {
                                                if (element.getAlarmState().isEmpty()) {
                                                    return;
                                                }
                                                alarm.setAlarmSeverity(AlarmSeverity.CLEARED);
                                            }
                                            alarm.setElementID(ipaddress);
                                            alarm.setProbableCause(AlarmProbableCause.LINE_INTERFACE_FAILURE);
                                            box.getAlarmModel().addAlarm(alarm);
                                        }
                                    });
                                }
                            }
                        }
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        };
        linkCheckThread.start();
    }

 

 将告警放置在一个告警表格中:



 同时,让告警表和拓扑图共享一个DataBox,于是告警就会在拓扑中显示:

 


 

最终效果以及源代码下载

这是用这个小程序探索我们办公室的网络结构。你的呢?也可以发上来看看!

 




源代码、第三方lib包、可执行包、run.bat都在附件中,请大家自行下载。请确保安装了JAVA 6。解压后双击run.bat即可。在弹出的对话框中点击start按钮即可进行网络自动发现。

 

源代码和可执行文件点击下载

 

GOOD LUCK & HAVE FUN!

 

 

  • 大小: 21.9 KB
  • 大小: 14.5 KB
  • 大小: 3.7 KB
  • 大小: 36.6 KB
  • 大小: 105.1 KB
  • 大小: 13.2 KB
  • 大小: 4.9 KB
  • 大小: 18.4 KB
  • 大小: 87.9 KB
分享到:
评论
27 楼 neusoft_jerry 2013-02-25  
哥,你能不用twaver写吗?用点儿开源的东西
26 楼 rsic 2012-10-24  
太牛了
搂主我已经深深折服了
效果非常棒,创意也非常好
25 楼 liubingjun 2011-04-13  
你好,请问,除了本机所在的网段外,假如再模拟出一个网段,也就是存在多个网段,该如何实现呀?
private String getNetworkSegmentPrefix() {
try {
InetAddress addr = InetAddress.getLocalHost();
String localHostName = addr.getHostAddress();
String netPrefix = localHostName.substring(0, localHostName
.lastIndexOf("."));
return netPrefix;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
24 楼 comsci 2010-08-31  
这篇文章比较有意义,值得一读。。。不知道楼主的这个GUI中的节点拓扑图的程序是基于哪个SWING组件的呢?
23 楼 爪哇岛岛主 2010-08-29  
 
22 楼 爪哇岛岛主 2010-08-29  
恩,不错啊,加油加油
21 楼 sunsonw 2010-08-28  
snake1987 写道
拓扑没我们公司的好看,
楼主,这可不是你的水平哦~


你们的拓扑图啥样啊,给大家见识见识
20 楼 xiaozhonghua 2010-08-28  
xiaozhonghua 写道
power_zl 写道
xiaozhonghua 写道
yjheeq 写道
我的也是蓝屏,点击bat后,程序是跑起来了,可是我想关的时候,对不起,cmd窗口关不掉,然后突然蓝屏!!!

真是奇怪了。是ping网络时候蓝屏,还是启动就立刻蓝屏?

跟这位兄弟一样,是cmd窗口关不掉,然后就蓝屏

非常奇怪。大家可以在IDE里面跑一下代码看是否有同样的问题。

大家可以减少一下线程数量,改成5之类的,看是否会解决问题。
19 楼 kingwood2005 2010-08-28  
看来研究下代码还是可行的
18 楼 tenderuser 2010-08-27  
引用
如果本机的地址是192.168.1.122,那么所在的网段自然就是192.168.1.0。

这个是不是有点问题?  难道网段一定会是192.168.1.0?  这个要考虑掩码吧?    感觉楼主失误了 
17 楼 1927105 2010-08-27  
lz能否传一个Twaver软件过来,,,
16 楼 xiaozhonghua 2010-08-27  
power_zl 写道
xiaozhonghua 写道
yjheeq 写道
我的也是蓝屏,点击bat后,程序是跑起来了,可是我想关的时候,对不起,cmd窗口关不掉,然后突然蓝屏!!!

真是奇怪了。是ping网络时候蓝屏,还是启动就立刻蓝屏?

跟这位兄弟一样,是cmd窗口关不掉,然后就蓝屏

非常奇怪。大家可以在IDE里面跑一下代码看是否有同样的问题。
15 楼 power_zl 2010-08-27  
xiaozhonghua 写道
yjheeq 写道
我的也是蓝屏,点击bat后,程序是跑起来了,可是我想关的时候,对不起,cmd窗口关不掉,然后突然蓝屏!!!

真是奇怪了。是ping网络时候蓝屏,还是启动就立刻蓝屏?

跟这位兄弟一样,是cmd窗口关不掉,然后就蓝屏
14 楼 odd2008 2010-08-27  
充分利用开源的东西。
8错8错
13 楼 xiaozhonghua 2010-08-27  
yjheeq 写道
我的也是蓝屏,点击bat后,程序是跑起来了,可是我想关的时候,对不起,cmd窗口关不掉,然后突然蓝屏!!!

真是奇怪了。是ping网络时候蓝屏,还是启动就立刻蓝屏?
12 楼 yjheeq 2010-08-27  
我的也是蓝屏,点击bat后,程序是跑起来了,可是我想关的时候,对不起,cmd窗口关不掉,然后突然蓝屏!!!
11 楼 xiaozhonghua 2010-08-27  
power_zl 写道
程序经常假死,然后直接蓝屏

运行两次,蓝屏两次了

哦?这么厉害?奇怪。其他朋友有蓝屏的吗?程序也没干什么啊。
10 楼 evan1234 2010-08-27  
Swing做出来的东西还是挺漂亮的嘛,呵呵!
学习一下!
9 楼 xiaozhonghua 2010-08-27  
晨星★~雨泪 写道
貌似很多机器检测不到?

嗯,java的Ping确实不是很好用。可以试试这种ping,看是否好些(我也没用过):

Socket t = new Socket(args[0], 7);
DataInputStream dis = new DataInputStream(t.getInputStream());
PrintStream ps = new PrintStream(t.getOutputStream());
ps.println("Hello");
String str = is.readLine();
if (str.equals("Hello"))
  return true;
else
  return false;
t.close();
8 楼 dajian 2010-08-27  
snake1987 写道
拓扑没我们公司的好看,
楼主,这可不是你的水平哦~




LZ也就举个个demo,要好看全靠美工

拓扑没我们公司的好看   (当然我们公司请了专业设计公司操刀界面)

相关推荐

    聚生网管破解版本 聚生网管破解版本

    聚生网管破解版本 聚生网管破解版本 聚生网管破解版本

    聚生网管2.11完美破解版

    聚生网管2.11完美破解版下载|聚生网管2010无限制版 聚生网管系统是一款强大并极富创意的局域网网络管理软件,它可以部署到局域网的任意一台电脑上,不需要做端口镜像,HUB或者代理服务器设置,就可以实现禁止P2P下载,...

    360安全卫士企业版|网管版|奇安信网管版客户端离线安装包

    360企业网管版离线安装,需要的亲,下载了, 国际领先多引擎查杀技术:全面清除病毒木马,每日采集新样本数大于1000万。 全球最大的云安全系统:1秒极速解决新威胁,日均样本分析能力大于8000万。 全网修复漏洞:...

    聚生网管破解版

    1、打开聚生网管的正式版安装光盘,双击光盘里面的聚生网管系统主程序:Netsene 2、不需要做任何特殊设置,一直点击“下一步”直到安装完成,部署完成。 3、开始——>程序——>聚生网管,第一次启动聚生网管系统,...

    聚生网管 标准版 聚生网管 标准版 聚生网管 标准版 聚生网管 标准版

    聚生网管 标准版 聚生网管 标准版 聚生网管 标准版 聚生网管 标准版 聚生网管 标准版 聚生网管 标准版 聚生网管 标准版 聚生网管 标准版

    超级网管V5.2破解版,一个很好的网管软件

    超级网管V5.2破解版, 是一个很好 的网络管理 软件 。

    360安全卫士企业版 网管版 免费版天擎5.0.6.1570

    360安全卫士企业版 网管版 免费版天擎5.0.6.1570,官方下载绝版资源。 奇安信网管版(原奇安信企业版)是面向企业级用户推出的专业安全解决方案,全功能不限终端数,提供全网统一体检、打补丁、杀病毒、开机加速 、...

    U2000网管软件实施手册 网管系统

    * 安装光盘:Windows操作系统补丁盘、SQL server标准版、网管软件。 * 安装软件包:Windows操作系统补丁包、SQL server标准版、基础组件、核心组件、传送域组件、IP域组件、接入域组件。 * 安装程序包要求解压到...

    聚生网管(无限制版) v2011.5.18.18简体中文破解版LanQos

    聚生网管(无限制版) v2011.5.18.18简体中文破解版LanQos

    聚生网管_2010_破解版(解除限制)

    聚生网管系统全方位介绍 ——限制P2P下载、聊天、炒股、玩游戏、上网带宽国内最强、部署最快捷、使用最简单! 聚生网管是国内最早的专业网管软件之一。2004年底推出了聚生网管系统的第一个商用版本,经过长达七年...

    U2000网管软件实施手册.pdf

    * 安装光盘:Windows 操作系统补丁盘、SQL Server 标准版、网管软件、基础组件、核心组件、传送域组件、IP 域组件、接入域组件。 * 安装软件包:Windows 操作系统补丁包、SQL Server 标准版、基础组件、核心组件、...

    聚生网管绿色破解版

    真正可以有效地控制各种P2P工具(P2P下载控制、P2P视频工具),封堵P2P工具为国内网管软件之最;真正实现对带宽的动态、精确、智能控制,便于管理员实时掌控局域网的网络资源使用状况;可以对网址浏览、各种聊天、...

    U2000网管安装工具

    **U2000网管安装工具详解** U2000网管系统,全称为华为统一服务管理平台,是一款专业用于网络管理和维护的软件。它集成了多种网络设备和服务的监控、配置、故障处理和性能管理功能,适用于各类企业和数据中心的网络...

    eNetTest 网管内网单机测速工具

    eNetTest 网管内网单机测速工具eNetTest 网管内网单机测速工具eNetTest 网管内网单机测速工具eNetTest 网管内网单机测速工具eNetTest 网管内网单机测速工具eNetTest 网管内网单机测速工具eNetTest 网管内网单机测速...

    天易成网管 v4.61 官方破解版

    天易成网管软件是一款上网行为管理软件,俗称网管专用软件。没错,这款软件就是给网管量身打造的,网管使用它可以随时随地监控所有局域网内的电脑上网行为,轻松实现封游戏、封下载、过滤网页等功能,用起来非常的...

    网管必备教程 网管必备教程 网管必备教程

    网管必备教程 网管必备教程 网管必备教程 网管必备教程

    聚生网管 反聚生网管最新版免费下载

    聚生网管 反聚生网管最新版免费下载 聚生网管 反聚生网管最新版免费下载 聚生网管 反聚生网管最新版免费下载 聚生网管 反聚生网管最新版免费下载 聚生网管 反聚生网管最新版免费下载 聚生网管 反聚生网管最新版免费...

    免费移动版OLT网管系统.apk

    免费移动版OLT网管系统华为OLT网管系统移动端APP For 安卓:手机版一键注册光猫,适合做小区宽带、宽带运营使用。

    网管微信DAT转JPG使用说明.docx

    网管微信 DAT 转 JPG 使用说明 本文档提供了《天才小网管微信 DAT 转 JPG》软件的使用说明,该软件能够将微信在聊天过程中收发的图片文件转换成普通的图片,方便用户清理硬盘空间。下面是软件的使用步骤和注意事项...

    华为5G网管U2020操作指导书.doc

    "华为5G网管U2020操作指导书" 华为5G网管U2020操作指导书是华为公司推出的5G网管系统操作指导手册,旨在帮助用户快速掌握华为5G网管U2020的使用方法和操作步骤。该指导书涵盖了华为5G网管U2020的登录路径、常用模块...

Global site tag (gtag.js) - Google Analytics