我正试图创建一个小型应用程序来管理snmp设备,并且一开始我想获取系统信息。
我正在使用snmp4j版本2.7.0,java 1.8,并且设备使用了snmpv3。 首先,我想同步获取数据。 我尝试通过两种方式做到这一点,但我一直在超时。
这是我的代码
//Normal request
public class SynchronouslySnmp
{
protected String PORT="/161";
protected String PROTOCOL="udp:";
protected SnmpData snmpData;
protected Snmp snmp;
public SynchronouslySnmp(SnmpData snmpData)
{
this.snmpData=snmpData;
}
public void start()
{
createSNMPsession();
addSnmpUser();
sendSnmp();
}
private void sendSnmp()
{
// send the PDU
ResponseEvent response;
try
{
response = snmp.send(getPDU(), getTarget());
// extract the response PDU (could be null if timed out)
PDU responsePDU = response.getResponse();
// extract the address used by the agent to send the response:
if(responsePDU == null)
{
System.out.println("ERROR: table OID [" + SnmpContants.system + "] time out" );
}
else
{
Address peerAddress = response.getPeerAddress();
System.out.println("pdu: "+responsePDU.toString());
System.out.println("Address: "+peerAddress.toString());
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
snmp.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
protected void createSNMPsession()
{
TransportMapping<? extends Address> transport;
try
{
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
transport.listen();
//snmp.listen();
}
catch (IOException e)
{
e.printStackTrace();
}
}
protected void addSnmpUser()
{
// add user to the USM
snmp.getUSM().addUser(new OctetString(snmpData.getUsmUser()),
new UsmUser(new OctetString(snmpData.getUsmUser()),
snmpData.getAuthProtocol(),
new OctetString(snmpData.getAuthPassword()),
snmpData.getPrivProtocol(),
new OctetString(snmpData.getPrivPassword())));
}
protected Target getTarget()
{
// create the target
UserTarget target = new UserTarget();
Address targetAddress = GenericAddress.parse(PROTOCOL+snmpData.getIpAddress()+PORT);
target.setAddress(targetAddress);
target.setRetries(snmpData.getRetryTimes());
target.setTimeout(snmpData.getTimeout());
target.setVersion(snmpData.getSnmpVersion());
target.setSecurityLevel(snmpData.getSecurityLevel());
target.setSecurityName(new OctetString(snmpData.getUsmUser()));
return target;
}
protected PDU getPDU()
{
// create the PDU
PDU pdu = new ScopedPDU();
pdu.add(new VariableBinding(SnmpConstants.system));
pdu.setType(PDU.GETBULK);
return pdu;
}
}
我尝试使用treeUtil,但出现了与“普通”请求中相同的错误,以下是我的代码
public class SynchronouslySnmpUsingTree extends SynchronouslySnmp
{
private OID tableOid;
private LinkedHashMap<String, List<VariableBinding>> resultMap;
public SynchronouslySnmpUsingTree(SnmpData snmpData)
{
super(snmpData);
resultMap = new LinkedHashMap<String, List<VariableBinding>>();
tableOid=new OID(".1.3.6.1.2.1.1");
createSNMPsession();
addSnmpUser();
sendSnmp();
}
private void sendSnmp()
{
try
{
TreeUtils treeUtils = new TreeUtils(snmp, new PDUFactory()
{
@Override
public PDU createPDU(MessageProcessingModel arg0) {
return getPDU();
}
@Override
public PDU createPDU(Target arg0) {
return getPDU();
}
});
List<TreeEvent> events = treeUtils.getSubtree(getTarget(), tableOid);
if (events == null || events.size() == 0)
{
System.out.println("Error: Unable to read table...");
return;
}
for (TreeEvent event : events)
{
if (event != null && !event.isError())
{
VariableBinding[] varBindings = event.getVariableBindings();
if (varBindings != null && varBindings.length != 0)
{
for (VariableBinding varBinding : varBindings)
{
if (varBinding != null)
{
OID oid = varBinding.getOid();
List<VariableBinding> binds = resultMap.get(oid.toString());
if( binds == null)
{
binds = new ArrayList<VariableBinding>();
resultMap.put(oid.toString(), binds);
}
binds.add(varBinding);
}
}
}
}
else
{
System.out.println("Error: table OID [" + tableOid + "] " + event.getErrorMessage());
continue;
}
}
}
catch(Throwable t)
{
System.out.println("Failed operation: getMibTableWithNext");
t.printStackTrace();
}
finally
{
try
{
snmp.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
主要功能
public static void main(String[] args){
SynchronouslySnmp synchronouslySnmp =new SynchronouslySnmp (new SnmpData());
synchronouslySnmp.start();
SynchronouslySnmpUsingTree synchronouslySnmpUsingTree = new SynchronouslySnmpUsingTree(new SnmpData());
}
运行程序的结果
Error: table OID [1.3.6.1.2.1.1] time out); <---nurmal
Error: table OID [1.3.6.1.2.1.1] Request time out); <---tree
我看着https://www.snmp4j.org/html/faq.html
为什么发送请求时我总是超时(响应== null)?
可能您忘记了在发送请求之前调用TransportMapping(一次)或Snmp类的listen()方法。
但是我在createSNMPsession()方法中做到了 那我在做什么错? 谢谢。 :)
答案 0 :(得分:0)
因此,我整整一整天都没头脑,答案就附在需要知道如何将SNMPV3与SNMP4J结合使用的任何人上。
让我们从正常的请求开始。 很好的问题是我将PDU与GETBULK一起使用,但是我没有设置“最大重复次数”,因此默认值为0,并且我得到了空的VBS
要修复它,只需使用:
protected PDU getPDU()
{
// create the PDU
PDU pdu = new ScopedPDU();
pdu.add(new VariableBinding(SnmpConstants.system));
pdu.setType(PDU.GETBULK);
pdu.setMaxRepetitions(10);//or any number you wish
return pdu;
}
对于树问题,无需定义最大重复次数,这是getSubTree的全部要点。 因此,问题在于我将以秒为单位的timeOut设置为30,而不是将Millisec设置为30000的愚蠢错误。 但后来我得到了更大的错误“ Agent没有按字典顺序返回变量绑定”。 墙来修复它,我用:
treeUtils.setIgnoreLexicographicOrder(true);
List<TreeEvent> events = treeUtils.getSubtree(getTarget(), tableOid);
if (events == null || events.size() == 0)
{
System.out.println("Error: Unable to read table...");
return;
}
.
.
.
if( binds == null)
{
binds = new ArrayList<VariableBinding>();
binds.add(varBinding);
resultMap.put(oid.toString(), binds);
}