SNMP 修改SNMP4J消息内容
2014-11-13 16:11
190 查看
我记得上次就有人说我这种做法
上次是因为我要在SNMP4J协议消息中增加两个特殊的OID来做为参数传递,遭到一些人质疑,认为是无用的
其实别的不说,我只想说一句:业务要求你这样你能怎么得,别跟我扯技术
我预计这次又得早质疑了,不过质疑你们就质疑吧,我们这次要求就是这样的
因为我们和远端机器调用时他们需要做数据流截取,所以我们必须打包一下我们这个SNMP协议包的大小
就是说这次的需求是,在SNMP协议原来基础上,发送消息时增加两个字节的消息长度信息
先来说发送时
其实SNMP我理解的话就是一种消息格式,最后还是通过TCP或UDP发送的,默认是通过UDP发送的
你通过Snmp的send方法一直向下找,可以看到
你到DefaultUdpTransportMapping这个类中看即可
他的sendMessage方法负责把组装后的SNMP消息包,根据地址,使用UDP协议发送出去
所以要修改SNMP4J发送的内容,在这里下手
message[] 数组就是发送的内容,这里我们做下手脚
简单修改为他的消息包增加了头消息长度属性
为了看效果,你可能会马上去运行一下,但是你不能这么做,修改之后的消息包已经不再“正确”,SNMP4J会进行一下检查,如果不对是不可能解析的
所以我们在接收消息时要除掉头消息
还是这个类,他有一个内部类 ListenThread 是一个线程类用来监听消息
他搞了一个缓冲区来包装返回的消息内容,然后给了一个方法,我们就在这里处理
这样就可以运行测试,发现没有影响,但是如果你查看发送的字节流就会发现增加了两个字节
相关人不要质疑了,需求就是这样的,没办法,我已经很不容易了!
请您到ITEYE看我的原创:http://cuisuqiang.iteye.com
或支持我的个人博客,地址:http://www.javacui.com
src.zip (384.2 KB)
下载次数: 17
上次是因为我要在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
src.zip (384.2 KB)
下载次数: 17
相关文章推荐
- SNMP 修改SNMP4J消息内容 之TCP发送模式
- SAP修改消息内容和报错类型(SE91和OBA5)
- openfire源码修改聊天消息发送内容
- 截取粘贴消息并修改粘贴的内容
- openfire源码修改聊天消息发送内容
- 让客户端javascript修改的内容在服务端也能记忆的一个简单例子
- 使用正则表达式,进行批量修改字符串中的匹配内容
- 修改flash文件内容
- Application_Start事件中修改配置文件内容
- ATLServer WebService 如何返回任意内容的 SOAP 消息给客户 —— 改写atlsoap.h
- 添加/删除/修改数据库内容
- javascript动态修改标签内容
- 用Ajax实现不刷新页面修改内容
- 修改 OleInsertDialog 显示内容
- Liferay Portal额外研究(四):修改用户登录后的默认布局和内容
- [转]微软拟扩展RSS2.0 订阅者可修改内容
- blog.com.cn网志修改内容
- strcat越界不产生异常,但修改相临存储区的内容
- 修改myelipse中deploy内容的方法
- delphi开发修改并提交Web表单内容