SNMP4J服务端连接超时问题解决方案
程序员文章站
2022-03-08 10:05:26
我们的网络管理中心作为管理中心,是服务端!各个被管设备通过交换机作为客户端与网管中心进行通信,使用的tcp/ip协议!snmp只是一种协议包,snmp4j作为snmp使用的java工具包,提供了方便安...
我们的网络管理中心作为管理中心,是服务端!各个被管设备通过交换机作为客户端与网管中心进行通信,使用的tcp/ip协议!
snmp只是一种协议包,snmp4j作为snmp使用的java工具包,提供了方便安全的工具包功能!
但是在使用中发现一个问题就是,服务端与客户端发送消息时,发送数次后就不再发送数据了!网络抓包也抓不到,跟踪断点到snmp4j的代码中发现了这样一个问题!
/** * 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(); } serverthread.sendmessage(address, message); }
我们可以看到,他与udp的不同是,使用了一个服务的线程!
public void sendmessage(address address, byte[] message) throws java.io.ioexception { socket s = null; socketentry entry = (socketentry) sockets.get(address); if (logger.isdebugenabled()) { logger.debug("looking up connection for destination '" + address + "' returned: " + entry); logger.debug(sockets.tostring()); } if (entry != null) { s = entry.getsocket(); } if ((s == null) || (s.isclosed()) || (!s.isconnected())) { if (logger.isdebugenabled()) { logger.debug("socket for address '" + address + "' is closed, opening it..."); } pending.remove(entry); socketchannel sc = null; try { // open the channel, set it to non-blocking, initiate // connect sc = socketchannel.open(); sc.configureblocking(false); sc .connect(new inetsocketaddress( ((tcpaddress) address).getinetaddress(), ((tcpaddress) address).getport())); s = sc.socket(); entry = new socketentry((tcpaddress) address, s); entry.addmessage(message); sockets.put(address, entry); synchronized (pending) { pending.add(entry); } selector.wakeup(); logger.debug("trying to connect to " + address); } catch (ioexception iox) { logger.error(iox); throw iox; } } else { entry.addmessage(message); synchronized (pending) { pending.add(entry); } selector.wakeup(); } }
他从一个map中去获得连接 socketentry ,然后得到连接对象socket!
判断socket是否有效,有效则直接发送,无效则创建连接后再发送!
然后我找到这样一段代码
private synchronized void timeoutsocket(socketentry entry) { if (connectiontimeout > 0) { socketcleaner.schedule(new sockettimeout(entry), connectiontimeout); } }
也就是说服务端会自己检查的连接并且去清除他!
我尝试设置 connectiontimeout 的值
private void init() throws unknownhostexception, ioexception { threadpool = threadpool.create("trap", 2); dispatcher = new multithreadedmessagedispatcher(threadpool,new messagedispatcherimpl()); // 本地ip与监听端口 listenaddress = genericaddress.parse(system.getproperty("snmp4j.listenaddress", "tcp:192.168.9.69/5055")); defaulttcptransportmapping transport; transport = new defaulttcptransportmapping((tcpaddress) listenaddress); transport.setconnectiontimeout(0); snmp = new snmp(dispatcher, transport); snmp.getmessagedispatcher().addmessageprocessingmodel(new mpv1()); snmp.getmessagedispatcher().addmessageprocessingmodel(new mpv2c()); snmp.getmessagedispatcher().addmessageprocessingmodel(new mpv3()); usm usm = new usm(securityprotocols.getinstance(), new octetstring(mpv3.createlocalengineid()), 0); securitymodels.getinstance().addsecuritymodel(usm); snmp.listen(); }
增加一行代码 设置defaulttcptransportmapping的超时时间是 0 !
然后就没有问题了!
虽然临时解决了问题,但是由于对snmp4j不够深入了解,我怕问题恐怕不是这样的!
我在此也希望使用snmp4j为工具,且作为服务端,在发送数据时有问题的解决方法!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: 家庭自制鱼火锅配菜清单到底有哪些
推荐阅读