我通过 snmp4j java 库向第一个 snmpv3 服务器发送 SNMP v3 请求,它工作正常。通过 snmp4j 库向第二个 snmpv3 服务器发送 SNMP v3 请求也可以正常工作。但是,如果我从同一程序中的两个不同线程发送到两台服务器,如下所示,其中一个会给出空响应 如下:-
203> 响应 PDU == null :
错误:空 地址:空 来源:com.x.x.x.SnmpV2@755ca288).
我敢打赌,由于 SecurityModels 是一个单例类,因此下面两行可能会造成混乱。
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
以下是代码:-
在多线程环境中使用 v3 的 snmp4j 的任何经验...
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthSHA;
import org.snmp4j.security.PrivAES128;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
public class MultiThreadedSnmpV3Request {
public static void main(String[] args) throws Exception {
MultiThreadedSnmpV3Request requests = new MultiThreadedSnmpV3Request();
new Thread(() -> {
try {
requests.firstServerRequest();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
requests.secondServerRequest();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
private void firstServerRequest() throws Exception {
String targetAddress = "udp:10.99.220.203/161";
String userName = "xxxx";
OID authProtocol = AuthSHA.ID;
String authPassphrase = "f8T7wWXeJ6brNeNF";
OID privProtocol = PrivAES128.ID; // PrivAES256.ID;
String privPassphrase = "KpbnkSJrP5Kgbhqb";
// build a PDU with all the OIDs
UserTarget target = new UserTarget();
target.setTimeout(5000);
target.setVersion(SnmpConstants.version3);
target.setAddress(GenericAddress.parse(targetAddress));
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setSecurityName(new OctetString(userName));
TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
SnmpV2 snmp = new SnmpV2(transport);
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
// add user to the USM
snmp.getUSM().addUser(new OctetString(userName), new UsmUser(new OctetString(userName), authProtocol,
new OctetString(authPassphrase), privProtocol, new OctetString(privPassphrase)));
transport.listen();
ScopedPDU requestPDU = new ScopedPDU();
requestPDU.add(new VariableBinding(new OID("1.3.6.1.4.1.2021.2.1.2.1")));
requestPDU.setType(PDU.GET);
for (int i = 0; i < 20; i++) {
Thread.sleep(3000);
ResponseEvent re = snmp.send(requestPDU, target);
PDU responsePDU = re.getResponse();
if (responsePDU == null) {
System.out.println("1st Server > responsePDU == null :");
System.out.println("> Error : " + re.getError());
System.out.println("> Address : " + re.getPeerAddress());
System.out.println("> Source : " + re.getSource());
System.out.println("> User object : " + re.getUserObject());
} else if (responsePDU.getVariableBindings() != null) {
for (VariableBinding vb : responsePDU.getVariableBindings()) {
System.out.println("1st Server >> " + vb.getOid() + " --> " + vb.getVariable());
}
}
}
}
private void secondServerRequest() throws Exception {
String targetAddress = "udp:10.99.220.204/161";
String userName = "xxxx";
OID authProtocol = AuthSHA.ID;
String authPassphrase = "f8T7wWXeJ6brNeNF";
OID privProtocol = PrivAES128.ID; // PrivAES256.ID;
String privPassphrase = "KpbnkSJrP5Kgbhqb";
UserTarget target = new UserTarget();
target.setTimeout(5000);
target.setVersion(SnmpConstants.version3);
target.setAddress(GenericAddress.parse(targetAddress));
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setSecurityName(new OctetString(userName));
TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
// add user to the USM
snmp.getUSM().addUser(new OctetString(userName), new UsmUser(new OctetString(userName), authProtocol,
new OctetString(authPassphrase), privProtocol, new OctetString(privPassphrase)));
transport.listen();
ScopedPDU requestPDU = new ScopedPDU();
requestPDU.add(new VariableBinding(new OID("1.3.6.1.4.1.2021.2.1.2.1")));
requestPDU.setType(PDU.GET);
for (int i = 0; i < 20; i++) {
Thread.sleep(3000);
ResponseEvent re = snmp.send(requestPDU, target);
PDU responsePDU = re.getResponse();
if (responsePDU == null) {
System.out.println("2nd Server> responsePDU == null :");
System.out.println("> Error : " + re.getError());
System.out.println("> Address : " + re.getPeerAddress());
System.out.println("> Source : " + re.getSource());
System.out.println("> User object : " + re.getUserObject());
} else if (responsePDU.getVariableBindings() != null) {
for (VariableBinding vb : responsePDU.getVariableBindings()) {
System.out.println("2nd Server >> " + vb.getOid() + " --> " + vb.getVariable());
}
}
}
}
}
TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
// add user to the USM
snmp.getUSM().addUser(new OctetString(userName), new UsmUser(new OctetString(userName), authProtocol,
new OctetString(authPassphrase), privProtocol, new OctetString(privPassphrase)));
这些代码应该修改:
TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(new MessageDispatcherImpl(), transport);
SecurityProtocols.getInstance().addDefaultProtocols();
USM usm = new USM(SecurityProtocols.getInstance(), new
OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
usm.addUser(new OctetString(userName), new UsmUser(new OctetString(userName),authProtocol,new OctetString(authPassphrase), privProtocol,new OctetString(privPassphrase)));
MPv3 mPv3 = new MPv3(usm);
snmp.getMessageDispatcher().addMessageProcessingModel(mPv3);
感谢您的回答@li.py,但是对于以前版本的 SNMP4J,MPv3(USM usm) 构造函数不存在,是否有替代方案?