我记得上次就有人说我这种做法
上次是因为我要在SNMP4J协议消息中增加两个特殊的OID来做为参数传递,遭到一些人质疑,认为是无用的
其实别的不说,我只想说一句:业务要求你这样你能怎么得,别跟我扯技术
我预计这次又得早质疑了,不过质疑你们就质疑吧,我们这次要求就是这样的
因为我们和远端机器调用时他们需要做数据流截取,所以我们必须打包一下我们这个SNMP协议包的大小
就是说这次的需求是,在SNMP协议原来基础上,发送消息时增加两个字节的消息长度信息
先来说发送时
其实SNMP我理解的话就是一种消息格式,最后还是通过TCP或UDP发送的,默认是通过UDP发送的
你通过Snmp的send方法一直向下找,可以看到
你到DefaultUdpTransportMapping这个类中看即可
他的sendMessage方法负责把组装后的SNMP消息包,根据地址,使用UDP协议发送出去
public void sendMessage(Address targetAddress, byte[] message) throws java.io.IOException { InetSocketAddress targetSocketAddress = new InetSocketAddress(((UdpAddress)targetAddress).getInetAddress(), ((UdpAddress)targetAddress).getPort()); if (logger.isDebugEnabled()) { logger.debug("Sending message to "+targetAddress+" with length "+ message.length+": "+ new OctetString(message).toHexString()); } DatagramSocket s = ensureSocket(); s.send(new DatagramPacket(message, message.length, targetSocketAddress)); }
所以要修改SNMP4J发送的内容,在这里下手
message[] 数组就是发送的内容,这里我们做下手脚
/** * 使用UDP发送消息 * 崔素强进行修改,增加了消息长度字段,占用两个字节 */ public void sendMessage(Address targetAddress, byte[] message) throws java.io.IOException { // TODO 增加头字段 short length = (short)message.length; byte[] btlength = shortToByte(length); byte[] relmess = new byte[message.length + 2]; ByteBuffer bbuf = ByteBuffer.allocate(message.length + 2); bbuf.put(btlength); bbuf.put(message); bbuf.flip(); bbuf.get(relmess, bbuf.position(), bbuf.limit()); // 得到目前为止缓冲区所有的数据 InetSocketAddress targetSocketAddress = new InetSocketAddress( ((UdpAddress) targetAddress).getInetAddress(), ((UdpAddress) targetAddress).getPort()); if (logger.isDebugEnabled()) { logger.debug("Sending message to " + targetAddress + " with length " + relmess.length + ": " + new OctetString(relmess).toHexString()); } DatagramSocket s = ensureSocket(); s.send(new DatagramPacket(relmess, relmess.length,targetSocketAddress)); }
简单修改为他的消息包增加了头消息长度属性
为了看效果,你可能会马上去运行一下,但是你不能这么做,修改之后的消息包已经不再“正确”,SNMP4J会进行一下检查,如果不对是不可能解析的
所以我们在接收消息时要除掉头消息
还是这个类,他有一个内部类 ListenThread 是一个线程类用来监听消息
while (!stop) { DatagramPacket packet = new DatagramPacket(buf, buf.length, udpAddress.getInetAddress(), udpAddress.getPort()); try { try { socket.receive(packet); } catch (InterruptedIOException iiox) { if (iiox.bytesTransferred <= 0) { continue; } } if (logger.isDebugEnabled()) { logger.debug("Received message from "+packet.getAddress()+"/"+ packet.getPort()+ " with length "+packet.getLength()+": "+ new OctetString(packet.getData(), 0, packet.getLength()).toHexString()); } ByteBuffer bis; // If messages are processed asynchronously (i.e. multi-threaded) // then we have to copy the buffer's content here! if (isAsyncMsgProcessingSupported()) { byte[] bytes = new byte[packet.getLength()]; System.arraycopy(packet.getData(), 0, bytes, 0, bytes.length); bis = ByteBuffer.wrap(bytes); } else { bis = ByteBuffer.wrap(packet.getData()); } fireProcessMessage(new UdpAddress(packet.getAddress(), packet.getPort()), bis); } catch (SocketTimeoutException stex) { // ignore } catch (PortUnreachableException purex) { synchronized (DefaultUdpTransportMapping.this) { listener = null; } logger.error(purex); if (logger.isDebugEnabled()) { purex.printStackTrace(); } if (SNMP4JSettings.isFowardRuntimeExceptions()) { throw new RuntimeException(purex); } break; } catch (SocketException soex) { if (!stop) { logger.error("Socket for transport mapping " + toString() + " error: " + soex.getMessage(), soex); } stop = true; } catch (IOException iox) { logger.warn(iox); if (logger.isDebugEnabled()) { iox.printStackTrace(); } if (SNMP4JSettings.isFowardRuntimeExceptions()) { throw new RuntimeException(iox); } } }
他搞了一个缓冲区来包装返回的消息内容,然后给了一个方法,我们就在这里处理
// TODO 移除头字段 ByteBuffer bis; if (isAsyncMsgProcessingSupported()) { byte[] bytes = new byte[packet.getLength() - 2]; System.arraycopy(packet.getData(), 2, bytes, 0,bytes.length); bis = ByteBuffer.wrap(bytes); } else { byte[] bytes = new byte[packet.getData().length - 2]; System.arraycopy(packet.getData(), 2, bytes, 0,bytes.length); bis = ByteBuffer.wrap(bytes); } fireProcessMessage(new UdpAddress(packet.getAddress(), packet.getPort()), bis);
这样就可以运行测试,发现没有影响,但是如果你查看发送的字节流就会发现增加了两个字节
相关人不要质疑了,需求就是这样的,没办法,我已经很不容易了!
请您到ITEYE看我的原创:http://cuisuqiang.iteye.com
或支持我的个人博客,地址:http://www.javacui.com
相关推荐
1. **Trap接收与发送**:SNMP陷阱(Trap)是网络设备向管理站主动发送的报警消息,SNMP4J支持设置陷阱监听器来接收这些消息,同时也能主动发送自定义陷阱。 2. **Get请求与Response**:通过GET操作,可以获取网络...
SNMP4J是一个开源的Java库,提供了一个完整的SNMP实现,包括PDU构造、消息编码和解码、错误处理等功能。它支持SNMPv1、v2c和v3的安全性和认证机制。使用SNMP4J,开发者可以轻松地在Java应用中集成SNMP功能。 3. ...
SNMP4J提供了丰富的类和接口,如`Snmp`类用于发起SNMP请求,`Target`类定义了SNMP操作的目标,`PDU`类表示SNMP消息中的数据单元。 例如,以下是一个简单的SNMP GET请求的示例: ```java import org.snmp4j.*; ...
使用SNMP4J,开发者能够通过编写Java代码来实现对网络设备的操作,比如检索设备信息、修改设备配置、接收告警通知等。 在这份文档中,提到了几个SNMP4J中实现的操作,包括GET、GETNEXT、GETBULK、Walk和SET。 GET...
通过上述内容,你应能掌握使用snmp4j库进行SNMP操作的基本方法,包括获取和设置MIB值,发送TRAP,以及在SNMPv3环境下的安全配置。这个eclipse工程提供了一个实用的起点,帮助你开始在Java项目中集成SNMP功能。
`snmp4j-2.2.2.jar`是SNMP4J的主要库,包含了SNMP协议的实现,如PDU(Protocol Data Unit)的创建、消息处理、安全模型和认证机制。此版本支持SNMPv1、v2c和v3,提供了对不同安全级别的支持,包括无认证、基于密码的...
本文将深入探讨如何使用SNMP4J-Agent工具在个人计算机上模拟SNMP服务,以便进行测试和开发。 SNMP4J-Agent是SNMP4J项目的一部分,是一个开源的Java库,用于实现SNMP代理功能。它提供了丰富的API,可以方便地构建...
SNMP4J是一个开源的Java库,专门设计用于实现SNMP协议的客户端功能,使得开发者能够从网络设备中读取或设置管理信息。本篇文章将详细探讨如何使用SNMP4j库在Java中读取SNMP协议数据。 首先,了解SNMP是必要的。SNMP...
此外,还可以通过SNMP4J的NotificationOriginator接口发送Trap或Inform消息,以通知管理站网络设备的状态变化。 在提供的压缩文件列表中,"www.pudn.com.txt"可能是一个包含更多关于SNMP4J使用示例或MIB模拟细节的...
四、SNMP4J基本操作 使用SNMP4J,开发者可以执行以下基本操作: 1. Get:获取MIB对象的值。 2. Set:修改MIB对象的值。 3. GetNext:获取下一个MIB对象的值,用于遍历MIB树。 4. Trap:接收或发送陷阱(Trap)报文,...
SNMP4j是一个Java库,专门用于实现简单网络管理协议(SNMP)的应用程序。SNMP是一种广泛应用于网络设备管理的标准协议,它允许系统管理员远程监控和管理网络设备,如路由器、交换机、服务器等。SNMP4j是Java开发者在...
在这个“snmp4j中agent程序demo”中,我们将探讨SNMP代理的基本概念、Snmp4j库的使用以及如何创建一个简单的SNMP代理程序。 首先,理解SNMP代理的概念是至关重要的。SNMP代理是网络设备上的软件组件,负责收集设备...
**SNMP4J:网络管理的利器** SNMP4J是一个用Java编写的开放源码的简单网络管理协议(SNMP)实现库。这个库允许开发者构建能够与SNMP兼容的网络设备进行通信的应用程序。SNMP4J-2.5.6版本是其重要的里程碑,提供了对...
SNMP4j是一款开源的Java库,专门用于实现简单网络管理协议(SNMP)的应用程序。这个库使得Java开发者能够轻松地与支持SNMP的网络设备进行通信,从而监控、管理和配置网络基础设施。"SNMP4j帮助文件"是针对这款库的...
除了GET请求,`snmp4j` 还支持其他SNMP操作,如SET请求(用于修改设备配置)和Trap(用于接收设备发送的事件通知)。此外,`snmp4j` 提供了完整的SNMP版本支持,包括安全性增强的SNMPv3,可以设置安全模型、认证协议...
在SNMP4J中,首先需要设置一个TransportMapping,如UDPTransportMapping,它定义了SNMP消息的传输方式。接着,创建一个Session对象,绑定到TransportMapping,以建立与远程设备的连接。然后,可以使用PDU(Protocol ...
在Java环境中,我们通常会借助第三方库来处理SNMP协议,其中“snmp4j”是一个功能强大的开源库,专门用于实现SNMP协议的客户端功能。 snmp4j库提供了丰富的API,使得开发者能够轻松地与支持SNMP协议的设备进行通信...
SNMP4J-CLT是基于Java开发的一个强大的命令行工具,它允许用户与支持SNMP(简单网络管理协议)的设备进行交互。这个工具在任何支持Java的平台上都能运行,包括Windows、Linux、macOS等,这得益于Java的跨平台特性。...