之前写了一篇关于 SNMP 修改SNMP4J消息内容 的博客,但是当时只是针对UDP的,后来应用到TCP上后发现有一些问题,现在说一下解决方法
上一篇连接地址:http://cuisuqiang.iteye.com/blog/1584391
使用TCP发送时,由于Socket不知道数据流的长度,所以要增加数据包长度到包上,这才是真正的需求,是我上次理解错了
增加头信息与上一次一样,直接在发送时增加即可
找到类:DefaultTcpTransportMapping
找到发送方法:
public void sendMessage(Address address, byte[] message)
在发送时增加消息头
/** * Sends a SNMP message to the supplied address. * @param address * an <code>TcpAddress</code>. A <code>ClassCastException</code> is thrown * if <code>address</code> is not a <code>TcpAddress</code> instance. * @param message byte[] * the message to sent. * @throws IOException */ public void sendMessage(Address address, byte[] message) throws java.io.IOException { if (server == null) { listen(); } // TODO 增加头字段 short length = (short)(message.length + 2); byte[] btlength = shortToByte(length); byte[] relmess = new byte[length]; System.arraycopy(btlength, 0, relmess, 0, 2); System.arraycopy(message, 0, relmess, 2, message.length); serverThread.sendMessage(address, relmess); }
但是在接收时就遇到一个问题,底层接收后会直接验证数据流,如果你增加头信息,就不算是标准SNMP包了,SNMP4J就不会接收不会处理
在类:DefaultTcpTransportMapping 中有一个内部类:
class ServerThread implements WorkerTask
方法
private void readMessage(SelectionKey sk, SocketChannel readChannel, TcpAddress incomingAddress) throws IOException
提供对于数据流的处理,处理后将数据流返回到上层进行解析
在方法中有这样有这样的代码:
ByteBuffer byteBuffer = ByteBuffer.wrap(buf); byteBuffer.limit(messageLengthDecoder.getMinHeaderLength());
MessageLengthDecoder 接口用于标识SNMP数据包的一些属性解析方法,包括最小头字节和获得 MessageLength 对象
如果数据小于最小字节,那么直接抛弃不解析
同样在TCP发送类中有一个内部类来实现这个接口:
public static class SnmpMesssageLengthDecoder implements MessageLengthDecoder { public int getMinHeaderLength() { return MIN_SNMP_HEADER_LENGTH; } public MessageLength getMessageLength(ByteBuffer buf) throws IOException { MutableByte type = new MutableByte(); BERInputStream is = new BERInputStream(buf); int ml = BER.decodeHeader(is, type); int hl = (int)is.getPosition(); MessageLength messageLength = new MessageLength(hl, ml); return messageLength; } }
由于我们增加两个字节的长度,所以要重新写一个实现的接口
// TODO 自己定义的头解析 public static class SnmpMesssageLengthDecoderMe implements MessageLengthDecoder { public int getMinHeaderLength() { return MIN_SNMP_HEADER_LENGTH + 2; } public MessageLength getMessageLength(ByteBuffer buf) throws IOException { int hl = 4; int ml = decodeHeader(buf); MessageLength messageLength = new MessageLength(hl, ml); return messageLength; } public int decodeHeader(ByteBuffer is){ byte[] bt = is.array(); byte[] len = new byte[]{ bt[0], bt[1] }; return byteToShort(len) - 4; } /** * @功能 字节的转换与短整型 * @return 短整型 */ public synchronized static short byteToShort(byte[] b) { short s = 0; short s0 = (short) (b[1] & 0xff);// 最低位 short s1 = (short) (b[0] & 0xff); s1 <<= 8; s = (short) (s0 | s1); return s; } }
长度就是原来的 +2 ,MessageLength 的属性有两个,按照我的写法写可以解决问题,但是我不明白
int ml = BER.decodeHeader(is, type);
的含义,希望有明白的给说明一下
消息的长度实际上就是我们定义的头表示的长度 -4
这样流读取方法才能把我们发送的数据流完整读取出来
上次在转发到上层解析时的方法也要修改,因为现在修改的只是正常读取到所有的流,而返给上层的数据流是要截取掉这两个字节的
@SuppressWarnings("static-access") private void dispatchMessage(TcpAddress incomingAddress, ByteBuffer byteBuffer, long bytesRead) { byteBuffer.flip(); if (logger.isDebugEnabled()) { logger.debug("Received message from " + incomingAddress + " with length " + bytesRead + ": " + new OctetString(byteBuffer.array(), 0, (int)bytesRead).toHexString()); } ByteBuffer bis; if (isAsyncMsgProcessingSupported()) { byte[] bytes = new byte[(int)bytesRead - 2]; System.arraycopy(byteBuffer.array(), 2, bytes, 0, (int)bytesRead - 2); bis = ByteBuffer.wrap(bytes); } else { byte[] bytes = new byte[(int)bytesRead - 2]; System.arraycopy(byteBuffer.array(), 2, bytes, 0, (int)bytesRead - 2); bis = ByteBuffer.wrap(bytes); } // TODO 调用解析数据流 fireProcessMessage(incomingAddress, bis); }
这样就可以正常解析增加两个字节的数据包
请您到ITEYE看我的原创:http://cuisuqiang.iteye.com
或支持我的个人博客,地址:http://www.javacui.com
相关推荐
使用 SNMP4J 库可以轻松地实现 SNMP Trap 发送和接收,且支持多种传输协议,如 UDP 和 TCP。 Trap 发送 在 SNMP4J 库中,Trap 发送可以通过使用 `Snmp` 对象和 `CommandResponder` 接口来实现。`Snmp` 对象用于...
在SNMP4J中,你可以创建一个GetRequest PDU,指定要查询的对象标识符(OID),然后通过Transport(如UDP或TCP)发送请求。收到响应后,解析PDU获取结果。 4. GETNEXT操作: GETNEXT操作用于获取MIB中给定对象的下...
在提供的“snmp4j.pdf”文档中,你将找到更多关于如何使用SNMP4J的详细示例和教程,包括初始化设置、发送请求、处理响应、以及设置陷阱监听器等内容。这份文档将帮助你深入理解和应用SNMP4J库,以便在Java环境中有效...
**SNMP4J API文档详解** SNMP4J是一个开源的Java实现的简单网络管理协议(SNMP)库,它提供了全面的API用于开发SNMP应用程序。本文将深入解析SNMP4J API的核心概念和主要功能,帮助开发者理解和利用这个强大的工具...
SNMP4J 支持两种消息发送模式:同步发送模式和异步发送模式。同步发送模式也称阻塞模式,当管理端发送出一条消息之后,线程会被阻塞,直到收到对方的回应或者时间超时。异步发送模式也称非阻塞模式,当程序发送一条...
4. **发送PDU**:通过Session对象发送Get、Set或Trap请求,SNMP4J会自动封装这些请求为适当的PDU格式。 5. **处理响应**:定义事件监听器来处理接收到的响应,包括成功返回的数据、错误信息或者陷阱通知。 SNMP4J还...
接着,`Snmp`类是SNMP4J的核心,它实现了SNMP协议引擎,处理SNMP请求和响应的发送与接收。`Snmp`类提供了多种方法,如`get`, `set`, `trap`等,以执行SNMP操作。这些方法通常与`CommunityTarget`对象一起使用,来...
`snmp4j-agent-2.0.10a.jar`则是SNMP4J的代理扩展,它提供了构建SNMP代理所需的功能,如MIB对象的管理、变量绑定(Variable Binding)处理、陷阱(Trap)发送等。MIB(Management Information Base)是定义网络设备...
它基于TCP/IP协议栈,通过发送GET和SET请求来获取或修改网络设备的管理对象。 SNMP4j库为Java开发者提供了一个完整的SNMP解决方案,包括PDU(协议数据单元)的构建、编码、解码以及错误处理等功能。使用SNMP4j,你...
此外,还可以通过SNMP4J的NotificationOriginator接口发送Trap或Inform消息,以通知管理站网络设备的状态变化。 在提供的压缩文件列表中,"www.pudn.com.txt"可能是一个包含更多关于SNMP4J使用示例或MIB模拟细节的...
**SNMP4J文档概述** SNMP4J是一个开源的Java实现,用于支持简单网络管理协议(SNMP)的应用程序开发。它提供了完整的SNMPv1、SNMPv...通过深入理解和实践文档中的内容,你可以熟练地运用SNMP4J来监控和控制网络环境。
这个最新的API版本包括了`snmp4j-2.0.3.jar`,`snmp4j-2.0.3-javadoc.jar`以及`snmp4j-agent-2.0.5.jar`这三个组件,它们各自扮演着不同的角色。 1. **snmp4j-2.0.3.jar**: 这是SNMP4J的主要库文件,包含了SNMP协议...
SNMP4j是一款开源的Java库,专门用于实现简单网络管理协议(SNMP)的应用程序。这个库使得Java开发者能够轻松地与支持SNMP的网络设备进行通信,从而监控、管理和配置网络基础设施。"SNMP4j帮助文件"是针对这款库的...
SNMP4J支持多种传输层协议,如UDP(默认)和TCP,通过不同的TransportMapping实现。 4. **Security Models**: 对于SNMP v3,SNMP4J实现了USM、V1/2 Community-Based Security和Vacm Access Control Model。 5. ...
3. **PDU(Protocol Data Unit)操作**:SNMP4J提供了Get、Set、Trap等基本PDU操作,用于读取、修改网络设备状态或发送陷阱通知。 4. **事件处理**:SNMP4J的事件驱动模型允许开发者注册监听器以响应来自网络的SNMP...
1. **全面的SNMP支持**:SNMP4J不仅支持SNMP的基本操作,如GET、SET、TRAP,还支持非确认模式、同步和异步请求,以及SNMPv3的安全模型,包括用户安全模块(USM)、访问控制模型(ACM)和认证与加密机制。 2. **易于...
8. **异步编程模型**:SNMP4J提供了异步请求处理机制,允许开发者在一个非阻塞模式下发送SNMP请求,提高程序性能。相关的类如`AsyncRequest`和`FutureResponse`用于异步操作。 9. **错误处理和异常**:在源码中,...
SNMP4J是一个Java库,专门用于实现简单网络管理协议(SNMP)的应用程序。SNMP是一种广泛应用于网络设备管理的标准协议,它允许系统管理员监控和管理网络中的硬件、软件和网络服务。SNMP4J提供了对SNMPv1、SNMPv2c和...
SNMP4J是一个Java实现的简单网络管理协议(SNMP)的应用编程接口(API),它为开发者提供了在Java环境中开发SNMP应用的功能。这个最新的2.3.1版本是官方发布的,确保了稳定性和兼容性。下面将详细介绍SNMP4J的几个...
2. **事件驱动模型**: SNMP4J基于事件驱动的设计模式,允许应用程序订阅并处理SNMP响应和陷阱事件。 3. **灵活的PDU处理**: 支持所有类型的SNMP协议数据单元(PDU),包括Get, Set, GetNext, GetBulk等操作,以及 ...