`
xiaozhonghua
  • 浏览: 254768 次
  • 性别: 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域组件、接入域组件。 * 安装程序包要求解压到...

    聚生网管Netsense(局域网限速)2.11中文破解版

    聚生网管系统是一款强大并极富创意的局域网网络管理软件,它可以部署到局域网的任意一台电脑上,不需要做端口镜像,HUB或者代理服务器设置,就可以实现禁止P2P下载,禁止P2P视频,禁止QQ聊天工具,限制网址浏览,限制主机...

    聚生网管(无限制版) 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工具为国内网管软件之最;真正实现对带宽的动态、精确、智能控制,便于管理员实时掌控局域网的网络资源使用状况;可以对网址浏览、各种聊天、...

    EASY网管9.3.3破解版

    EASY网管9.3.3破解版 EASY网管9.3.3破解版

    U2000网管安装工具

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

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

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

    eNetTest 网管内网单机测速工具

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

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

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

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

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

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

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

Global site tag (gtag.js) - Google Analytics