【发布时间】:2012-03-08 13:03:53
【问题描述】:
我有一个 Java 中的 SNMP 陷阱应用程序,旨在侦听 SNMP 代理并在 JFrame 窗口中的 JTextArea 上打印收到的 SNMP 消息。
下面的第一部分是我的源代码,显示了类 TrapReceiver 的内容。在这个类中,listen 方法是最能发挥作用的地方。该类在一个 JFrame 类中被实例化,我打算在上面提到的 JTeaxtArea 上显示消息。我将 JTextArea 对象的引用、SNMP 代理 URL 和端口发送到类 TrapReceiver 的构造函数中,然后调用 TrapReceiver 对象的 run 方法以在 JFrame 实例之外的单独线程中开始执行。下面的第二部分展示了我如何在 JFrame 实例中实例化类 TrapReeceiver。
当我运行应用程序时,我注意到 JFrame 实例(即 GUI)正在冻结,并且在 JFrame 实例中提到的 JTeaxtArea 上没有打印任何消息,该实例实例化了下面第一部分中显示的类 TrapReeceiver。
我的问题是尽管 TRapReceiver 本身作为单独的线程执行,但为什么 JFrame 实例(即 GUI)会冻结?另外,我想知道这个冻结问题的可能解决方案是什么。提前致谢。
第一部分
package com.[Intenionally removed].snmp;
import java.io.IOException;
import javax.swing.JTextArea;
import org.snmp4j.*;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.security.Priv3DES;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.TransportIpAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.AbstractTransportMapping;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
public class TrapReceiver implements CommandResponder, Runnable {
private String targetSnmpAgentURL;
private int targetSnmpAgentPort;
private JTextArea outConsole;
public TrapReceiver() {
}
public TrapReceiver(JTextArea outConsole) {
this.outConsole = outConsole;
}
public TrapReceiver(JTextArea outConsole, String targetSnmpAgentURL, int targetSnmpAgentPort) {
this.targetSnmpAgentURL = targetSnmpAgentURL;
this.targetSnmpAgentPort = targetSnmpAgentPort;
this.outConsole = outConsole;
try {
listen(new UdpAddress(targetSnmpAgentURL + "/" + targetSnmpAgentPort));
} catch (IOException e) {
e.printStackTrace();
}
}
public final synchronized void listen(TransportIpAddress address) throws IOException {
AbstractTransportMapping transport;
if (address instanceof TcpAddress) {
transport = new DefaultTcpTransportMapping((TcpAddress) address);
} else {
transport = new DefaultUdpTransportMapping((UdpAddress) address);
}
ThreadPool threadPool = ThreadPool.create("DispatcherPool", 10);
MessageDispatcher mDispathcher = new MultiThreadedMessageDispatcher(
threadPool, new MessageDispatcherImpl());
// add message processing models
mDispathcher.addMessageProcessingModel(new MPv1());
mDispathcher.addMessageProcessingModel(new MPv2c());
// add all security protocols
SecurityProtocols.getInstance().addDefaultProtocols();
SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());
// Create Target
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
Snmp snmp = new Snmp(mDispathcher, transport);
snmp.addCommandResponder(this);
transport.listen();
System.out.println("Listening on " + address);
try {
this.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
/**
* This method will be called whenever a pdu is received on the given port
* specified in the listen() method
*/
@Override
public synchronized void processPdu(CommandResponderEvent cmdRespEvent) {
//System.out.println("Received PDU...");
outConsole.append("Received PDU...\n");
PDU pdu = cmdRespEvent.getPDU();
if (pdu != null) {
outConsole.append("Trap Type = " + pdu.getType() + "\n");
outConsole.append("Alarm Type: " + pdu.getVariableBindings().get(4) + "\n");
outConsole.append("Alarm Message: " + pdu.getVariableBindings().get(9) + "\n\n");
}
}
@Override
public void run() {
try {
listen(new UdpAddress(targetSnmpAgentURL + "/" + targetSnmpAgentPort));
} catch (IOException e) {
outConsole.append("\nError occured while listening to SNMP messages: \n" + e.getMessage() + "\n\n");
}
}
} //end of class TrapReceiver
第二部分
在下文中,我在线程中运行 TrapReceiver 类的实例。
private void jButtonStartListeningSNMPActionPerformed(java.awt.event.ActionEvent evt) {
Thread snmpThread =
new Thread(new TrapReceiver(jTextAreaSNMPAlarmOutput, jTextFieldSnmpAgentUrl.getText().trim(), Integer.parseInt(jTextFieldSnmpAgentPort.getText().trim())));
snmpThread.start()
}
【问题讨论】:
标签: java multithreading swing jframe snmp4j