import org.opennms.protocols.snmp.*;
import org.opennms.protocols.snmp.asn1.*;
import java.lang.System;
import java.util.*;
import java.net.*;
/** 이 클래스를 테스트 하기 위해서는 SNMP Agent가 필요합니다. */
public class SNMPGet implements SnmpHandler {
private SnmpParameters params;
private SnmpSession session;
public SNMPGet(InetAddress address, String community) {
try {
// 읽기를 위한 SNMP 커뮤니티 이름에 대한 문자열 정보를 포함하는 SnmpParameters 인스턴스 생성
// SnmpParameters 클래스는 SnmpSession에서 SNMP에이전트와의 통신에 사용할 SNMP 버전정보 및
// 커뮤니티 이름(읽기, 쓰기)에
// 대한 정보를 담당하게 된다. SnmpParameters 클래스를 사용하여 이와같은 정보들을 설정한다.
this.params = new SnmpParameters(community);
// SnmpSession 생성 SnmpSession은 manager와 agent 사이에 통신을 하기위한
// 클래스이다.(통신담당)
/*
* 다음은 SnmpSession 클래스에 API 문서의 설명이다. The SnmpSession is the main
* connection between the SNMP manager and the SNMP Agent.
* (SnmpSession은 SNMP 매니저와 SNMP 에이전트 사이의 주된 연결입니다.) All the request
* flow through this class. (모든 요청은 이 클래스를 통해서 흐릅니다.) To use the
* SnmpSession class a SnmpHandler class must be defined to process
* any errors or responses through the library. (SnmpSession 클래스를
* 사용하려면 반드시 에러 혹은 응답 라이브러리를 통해 프로세스에 정의된 SnmpHandler 클래스를 사용해야
* 합니다.)
*/
this.session = new SnmpSession(address, params);
// SnmpSession의 기본 Handler 등록
this.session.setDefaultHandler(this);
// session에 이벤트 헨들러가 이 클래스임을 지정한다. 이 클래스는 SnmpHandler인터페이스를
// implements 하였다.
// 추후 핸들러를 따로 구현한 클래스로 등록하자.
} catch (Exception e) {
System.out.println("SnmpSession객체 생성중 예외발생");
e.printStackTrace();
}
}// 기본생성자()=======================================================================
/*
* 다음 하단의 오버라이드한 메소드는 SnmpHandler 인터페이스 상속에 따른 추상 메소드 들이다. 각 이벤트에 대한 메소드들인데,
* 보시다시피 이터널에러, 정상적인 데이터 수신, 무응답에 따른 타임아웃 에러가 있다.
*/
@Override
public void snmpInternalError(SnmpSession session, int err, SnmpSyntax pdu) {
System.out.println("인터널 에러 발생");
// 메시지를 받으면 대기상태에서 해지되도록 한다.
synchronized (session) {
session.notify();
}
}// snmpInternalError()================================================================
@Override
public void snmpReceivedPdu(SnmpSession session, int command,
SnmpPduPacket pdu) {
System.out.println("데이터를 받았습니다.");
SnmpVarBind vb[] = pdu.toVarBindArray();
String value = null;
for (int i = 0; i < vb.length; i++) {
SnmpSyntax snmpValue = vb[i].getValue();
switch (snmpValue.typeId()) {
/*
* ANS이란? 플렛폼에 상관없이 데이터를 기술하기 위한 언어. 즉, 서로다른 환경을 갖고 있는 장비에서 동일한 데이터를
* 인식하기 위해 사용되는 문법을 말한다. 다른 기종간에 같은 데이터를 다르게 표현할 수 있는데 이러한 데이터들을
* 교환하고 다른 장치들끼리 인식할 수 있도록 하기 위해 만들어졌다.
*
* ASN은 CCITT와 ISO의 공동표준. 응용프로그램 데이터를 추상적으로 정의하거나 응용프로그램의 구조를 정의, 주로
* PDU들을 정의하는데 사용. ASN은 문법이며, switch - case 문에서 사용한 ASN1은 openNMS 에서
* 정의한 클래스로 패키지는 org.opennms.protocols.snmp.asn1 패키지에 있다. ASN1 클래스에
* 대한 설명은 다음과 같다.
*
* Public ASN.1 definitions. See
* "SNMPv1, SNMPv2, SNMPv3 and RMON 1 and 2, 3rd Ed." by William
* Stallings, Published by Addision Wesley for more information.
* (Public ASN.1은 정의. William Stallings(사람이름) 의한
* "SNMPv1, SNMPv2, SNMPv3 and RMON 1 and 2, 3rd Ed." 와 Addision
* Wesley가 발행한 정보를 참조하십시오.)
*/
case ASN1.OCTETSTRING: // static 맴버변수
value = new String(((SnmpOctetString) snmpValue).getString()); // 리턴하여
// 받은값을
// 문자열로
// 출력하기
// 위한
// 라인
break;
}
}// for()-------------------------------------------------------------------------
System.out.println(value);
// 메시지를 받으면 대기상태에서 해지되도록 한다.
synchronized (session) {
session.notify();
}
}// snmpReceivedPdu()==================================================================
@Override
public void snmpTimeoutError(SnmpSession session, SnmpSyntax pdu) {
System.out.println("Snmp 타임 아웃 ");
// 메시지를 받으면 대기상태에서 해지되도록 한다.
synchronized (session) {
session.notify();
}
}// snmpTimeoutError()=================================================================
public void send(String oid) // 문자열로 OID를 입력받는다.
{
try {
/*
* 데이터를 요구할 OID 정보 생성 SnmpVarBind클래스에 대한 설명은 다음과 같다. This class
* defined the SNMP variables that are transmitted to and from an
* agent. (이 클래스는 에이전트로부터 전달되는 SNMP 변수를 정의한 클래스입니다.) A variable is
* defined by its name (a SnmpObjectId) and its value (SnmpSyntax).
* (변수는 이름(a SnmpObjectId)과 그 이름에 대한 값(SnmpSyntax)에 의해서 정의됩니다.) The
* SnmpVarBind is used by the SnmpPduPacket class and uses
* SnmpObjectId along with any class that implements the SnmpSyntax
* interface. (SnmpVarBind 클래스는 SnmpPduPacket 클래스에서 사용하는 SnmpSyntax
* 인터페이스를 구현한 SnmpObjectId와 함께 사용됩니다)
*/
SnmpVarBind vblist[] = { new SnmpVarBind(oid) };
/*
* SNMP Request를 위한 PDU 생성, SNMP Request방법은 GET으로 정의 SnmpPduRequest에
* 대한 설명은 다음과 같다. The SnmpPduRequest defines the SNMPv1 and SNMPv2
* Protocol Data Unit (PDU) for certian message types.
* (SnmpPduRequest은 certian 메시지 유형에 대한 SNMPv1과 SNMPv2 프로토콜 데이터
* 단위(PDU)를 정의합니다.) The types include: GetRequest, GetNextRequest,
* SetRequest, SNMPv2-Trap, InformRequest, and Response. (형식은 다음과
* 같습니다. : GetRequest, GetNextRequest, SetRequest, SNMPv2-Trap,
* InformRequest 및 Response.) By default the class is constructed as
* a SNMP GetRequest, but can be defined to any of the accepted
* types. (기본적인 클래스는 SNMP GetReqeust로 생성됩니다. 하지만, 허용하는 어떠한 유형으로도 정의할
* 수 있습니다.)
*/
SnmpPduRequest req = new SnmpPduRequest(SnmpPduPacket.GET, vblist);
// SNMP Request에 해당하는 ID를 부여
/*
* 요청을 보낼 때 SNMP는 UDP방식으로 데이터를 전송하기 때문에, 그리고 약간의 응답시간이 존재하기 때문에 요청을
* 보낸 순서대로 응답이 오지 않는다. 순서가 불규칙 하므로 어떤 요청에 대한 응답인지를 알 수 있도록 하기 위해서
* 요청에 Request-id를 set 하여 보내도록 한다.
*/
req.setRequestId(SnmpPduPacket.nextSequence());
// session이라는 이름의 객체변수(SnmpSession)에 대해서 동기화 블록을 걸었다.
synchronized (session) {
// SNMP 에이전트에 데이터를 요청한다.
session.send(req);
// SNMP 데이터를 받을 때까지 대기 상태로 돌입한다. UDP방식이기 때문에 응답시간이 존재한다. 그 사이에
// SnmpSession을 통한 통신(연결)이 끊어지면 안된다.(받을 수 없다.)
session.wait(); // wait() 메소드가 InterruptedExcepion 을 발생시키 때문에 try
// - catch절을 사용함.
}// synchronized()-----------------------------------
}// try--------------------------------------------------
catch (InterruptedException ie) {
} finally {
session.close(); // 오라클DB도 보면 close를 하지 않으면 곤란한 상황이 발생한다.
// (예를 들어서 오라클DB의 경우 쿼리문을 전송했는데 응답이 오지 않는 경우 발생)
// 따라서 finally 예약어를 통해서 예외발생에 상관없이 반드시 close를 할 수 있도록 하였다.
}
}// send()===============================================================================
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.print("Agent Address : ");
String agentAddress = scanner.nextLine();
System.out.print("\nCommunity Name : ");
String communityName = scanner.nextLine();
System.out.println("\nOID (주의 : 생략 불가능 끝까지 입력할 것) : ");
String oid = scanner.nextLine();
// main메소드의 매개변수를 통해서 입력받도록 하였다. 추후 스캐너 이용하여 도스에서 입력가능하게 하자.
InetAddress address = InetAddress.getByName(agentAddress); // agent 주소
SNMPGet snmpGet = new SNMPGet(address, communityName); // 두번째 String 타입의
// 매개변수는 커뮤니티
// 네임이 들어간다.
snmpGet.send(oid); // 세번째 String 타입의 매개변수는 OID값이다.
}// main()===============================================================================
}//////////////////////////////////////////////////////////////////////////////////////////////
'SMTP' 카테고리의 다른 글
자바를 이용한 SNMP 데이터 가져오기 - 3 - (0) | 2013.07.25 |
---|---|
자바를 이용한 SNMP 데이터 가져오기 - 2 - (0) | 2013.07.25 |
자바를 이용한 SNMP 데이터 가져오기 - 1 - (0) | 2013.07.25 |