⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listeningcontext.java

📁 snmp zip 包开发snmp协议
💻 JAVA
字号:
// NAME//      $RCSfile: ListeningContext.java,v $// DESCRIPTION//      [given below in javadoc format]// DELTA//      $Revision: 3.6 $// CREATED//      $Date: 2006/02/09 14:30:19 $// COPYRIGHT//      Westhawk Ltd// TO DO///* * Copyright (C) 2005 - 2006 by Westhawk Ltd * <a href="www.westhawk.co.uk">www.westhawk.co.uk</a> * * Permission to use, copy, modify, and distribute this software * for any purpose and without fee is hereby granted, provided * that the above copyright notices appear in all copies and that * both the copyright notice and this permission notice appear in * supporting documentation. * This software is provided "as is" without express or implied * warranty. * author <a href="mailto:snmp@westhawk.co.uk">Tim Panton</a> */package uk.co.westhawk.snmp.stack;import java.io.*;import java.util.*;import uk.co.westhawk.snmp.event.*;import uk.co.westhawk.snmp.net.*;import uk.co.westhawk.snmp.util.*;/** * The ListeningContext class will enable this stack to receive packets. * This class replaces the deprecated DefaultTrapContext class. * The context will only start receiving (or listen for) packets when there is * at least one listener registered.  * * <p> * Two kind of listeners can be added;  * the normal and unhandled PDU listeners. * The normal PDU listeners are added via the * <code>addRawPduListener()</code> method,  * the unhandled PDU listeners are added via the  * <code>addUnhandledRawPduListener()</code>. * Both these listeners provide undecoded events. * </p> * * <p> * The SnmpContext classes provide functionality for decoded PDU and * trap events. These classes will register themselves via the * <code>addRawPduListener()</code> to the ListeningContext object and  * only pass the (decoded) event on if it matches their configuration. * </p> * * <p> * On UNIX and Linux operating systems the default port where PDUs and  * traps are sent (i.e. <em>161</em> and <em>162</em>) can only be opened  * as root. * </p> * * <p> * Only one process can listen on a certain port. To prevent more than * one ListeningContext listening on the same port, use the * ListeningContextPool class. * </p> * * @see ListeningContextPool * @see AbstractSnmpContext#addTrapListener * @see AbstractSnmpContext#addRequestPduListener * * @since 4_14 * @author <a href="mailto:snmp@westhawk.co.uk">Birgit Arkesteijn</a> * @version $Revision: 3.6 $ $Date: 2006/02/09 14:30:19 $ */public class ListeningContext implements ListeningContextFace, Runnable{    private static final String     version_id =        "@(#)$Id: ListeningContext.java,v 3.6 2006/02/09 14:30:19 birgit Exp $ Copyright Westhawk Ltd";    private static final String SOC_LOCK ="";    private static int      counter;    private ContextSocketFace  soc;    private Thread          me;    private String          basename;    private boolean         stopRequested;    protected int           maxRecvSize;    protected String        typeSocket;    protected int           hostPort;    protected String        bindAddr;    transient private RawPduReceivedSupport pduSupport, unhandledSupport;/** * Constructor, using the Standard socket type. * * @param port The local port where packets are received * * @see SnmpContextBasisFace#STANDARD_SOCKET */public ListeningContext(int port) {    this(port, null, SnmpContextBasisFace.STANDARD_SOCKET);}/** * Constructor, using the Standard socket type. * * If bindAddress is null, it will accept connections on * any/all local addresses. If you want to listen to * <ul> *    <li> *      IPv4 only interfaces, use address "0.0.0.0" *    </li> *    <li> *      IPv6 only interfaces, use address "::" *    </li> * </ul> * * @param port The local port where packets are received * @param bindAddress The local address the server will bind to  * * @see SnmpContextBasisFace#STANDARD_SOCKET */public ListeningContext(int port, String bindAddress) {    this(port, bindAddress, SnmpContextBasisFace.STANDARD_SOCKET);}/** * Constructor. * * If bindAddress is null, it will accept connections on * any/all local addresses. If you want to listen to * <ul> *    <li> *      IPv4 only interfaces, use address "0.0.0.0" *    </li> *    <li> *      IPv6 only interfaces, use address "::" *    </li> * </ul> * * * The typeSocket will indicate which type of socket to use. This way * different handlers can be provided for Netscape or Standard JVM. * The Netscape implementation will make the necessary security calls * to access connections that are not the applet's webserver. The KVM * version will be for small device support (e.g. Palm Pilot). * * <p> * Note, the TCP_SOCKET does not provide functionality to send a * response back. Listening on such a socket is only useful when * listening for traps. * </p> * * @param port The local port where packets are received * @param bindAddress The local address the server will bind to  * @param typeSocketA The type of socket to use. * * @see SnmpContextBasisFace#STANDARD_SOCKET * @see SnmpContextBasisFace#TCP_SOCKET * @see SnmpContextBasisFace#NETSCAPE_SOCKET * @see SnmpContextBasisFace#KVM_SOCKET */public ListeningContext(int port, String bindAddress, String typeSocketA){    hostPort = port;    bindAddr = bindAddress;    typeSocket = typeSocketA;    basename = ""+hostPort+"_"+bindAddr;    pduSupport = new RawPduReceivedSupport(this);    unhandledSupport = new RawPduReceivedSupport(this);    maxRecvSize = SnmpContextBasisFace.MSS;}public int getPort(){    return hostPort;}public String getBindAddress(){    return bindAddr;}public String getTypeSocket(){    return typeSocket;}public int getMaxRecvSize(){    return maxRecvSize;}public void setMaxRecvSize(int no){    maxRecvSize = no;}/** * This method will stop the thread listening for packets. * All transmitters, PDUs in flight and traplisteners will be removed * when run() finishes. * * <p> * It closes the socket. * The thread will actually stop/finish when the run() finishes. Since * the socket is closed, the run() will fall through almost instantly. * </p> * * <p> * Note that by calling this method the whole stack will stop listening * for packets on this particular port! The listeners added via the  * SnmpContext classes are affected as well. * </p> * * <p> * When you add a new listener, the context will start listening again. * </p> * * <p> * Note: The thread(s) will not die immediately; this will take about * half a minute. * </p> */public void destroy(){    synchronized(SOC_LOCK)    {        stopRequested = true;        if (soc != null)        {            if (AsnObject.debug > 12)            {                System.out.println(getClass().getName() + ".destroy(): Closing socket ");            }            soc.close();        }    }}/** * We wait for any incoming PDUs and fire a rawpdu received (undecoded) event  * if we do.  * <p> * The undecoded events are fired to all normal listeners (added via  * addRawPduListener()), until one of them consumes it.  * The SnmpContext classes will consume the event if it matches their  * configuration. * </p> * * <p> * If none of them consume the event, the undecoded events are fired to  * all unhandled PDU listeners (added via addUnhandledRawPduListener()),  * until one of them consumes it. * </p> * * @see RawPduReceivedSupport#fireRawPduReceived * @see #addRawPduListener(RawPduListener) * @see #addUnhandledRawPduListener(RawPduListener) */public void run(){    // while It is visible    while (!stopRequested)    {        // block for incoming packets        me.yield();         try        {            if (stopRequested)            {                break;            }            StreamPortItem item = soc.receive(maxRecvSize);            ByteArrayInputStream in = item.getStream();            String hostAddress = item.getHostAddress();            int port = item.getHostPort();            // read the bytes of the input stream into bu            int nb = in.available();            byte [] bu = new byte[nb];            in.read(bu);            in.close();            if (AsnObject.debug > 10)            {                SnmpUtilities.dumpBytes(getClass().getName()                     + ".run(): Received from "                    + hostAddress                      + ", from port " + port                    + ": ", bu);            }            KickProcessIncomingMessage thread =                   new KickProcessIncomingMessage(hostAddress, port, bu);            thread.start();        }        catch (java.io.IOException exc)        {            if (exc instanceof InterruptedIOException)            {                if (AsnObject.debug > 15)                {                    System.out.println(getClass().getName() + ".run(): Idle recv " + exc.getMessage());                }            }            else            {                if (AsnObject.debug > 0)                {                    System.out.println(getClass().getName() + ".run(): IOException: " + exc.getMessage());                }            }        }        catch (Exception exc)        {            if (AsnObject.debug > 0)            {                System.out.println(getClass().getName() + ".run(): Exception: " + exc.getMessage());                exc.printStackTrace();            }        }        catch (Error err)        {            if (AsnObject.debug > 0)            {                System.out.println(getClass().getName() + ".run(): Error: " + err.getMessage());                err.printStackTrace();            }        }    }    me = null;    soc = null;    pduSupport.empty();    unhandledSupport.empty();}public void addRawPduListener(RawPduListener listener)throws java.io.IOException{    pduSupport.addRawPduListener(listener);    startListening();}public void removeRawPduListener(RawPduListener listener){    pduSupport.removeRawPduListener(listener);    int nr = pduSupport.getListenerCount();    if (nr == 0)    {        destroy();    }}public void addUnhandledRawPduListener(RawPduListener listener)throws java.io.IOException{    unhandledSupport.addRawPduListener(listener);    startListening();}public void removeUnhandledRawPduListener(RawPduListener listener){    unhandledSupport.removeRawPduListener(listener);    int nr = unhandledSupport.getListenerCount();    if (nr == 0)    {        destroy();    }}/** * Creates the socket and starts listening for PDUs if we didn't do so already. * This method is called in addRawPduListener() and addUnhandledRawPduListener(). * * @exception java.io.IOException Thrown when the socket cannot be created. * @see #addRawPduListener * @see #addUnhandledRawPduListener */protected void startListening()throws java.io.IOException{    synchronized(SOC_LOCK)    {        if (soc == null)        {            soc = AbstractSnmpContext.getSocket(typeSocket);            soc.create(hostPort, bindAddr);            if (AsnObject.debug > 12)            {                System.out.println(getClass().getName() + ".startListening()"                    + ": soc.getLocalSocketAddress() = " + soc.getLocalSocketAddress());                System.out.println(getClass().getName() + ".startListening()"                    + ": soc.getRemoteSocketAddress() = " + soc.getRemoteSocketAddress());            }        }        if (me == null)        {            stopRequested = false;            me = new Thread(this, basename+"_Listen");            me.setPriority(me.NORM_PRIORITY);            me.start();        }    }}/** * Returns a string representation of the object. * @return The string */public String toString(){    StringBuffer buffer = new StringBuffer("ListeningContext[");    buffer.append("port=").append(hostPort);    buffer.append(", bindAddress=").append(bindAddr);    buffer.append(", socketType=").append(typeSocket);    buffer.append(", #rawPduListeners=").append(pduSupport.getListenerCount());    buffer.append(", #rawPduUnhandledListeners=").append(unhandledSupport.getListenerCount());    buffer.append("]");    return buffer.toString();}/** * Processes an incoming packet.  * * @see #run */protected void processIncomingMessage(String hostAddress,       int port, byte [] bu) throws DecodingException, IOException{    AsnDecoderBase rpdu = new AsnDecoderBase();    ByteArrayInputStream in = new ByteArrayInputStream(bu);    AsnSequence asnTopSeq = rpdu.getAsnSequence(in);    int version = rpdu.getSNMPVersion(asnTopSeq);    boolean isConsumed = pduSupport.fireRawPduReceived(version, hostAddress, port, bu);    if (isConsumed == false)    {        unhandledSupport.fireRawPduReceived(version, hostAddress, port, bu);    }}class KickProcessIncomingMessage extends Thread{    /**     * This class makes sure that dealing with an incoming packet is      * done at a separate thread so the ListeningContext can go back     * listening immediately.     * This will at some point be replaced by a Thread pool of     * some kind.     */    private String hostAddress;    private int port;    private byte [] bu;    KickProcessIncomingMessage(String newHostAddress, int newPort,         byte [] newBu)    {        hostAddress = newHostAddress;        port = newPort;        bu = newBu;        this.setPriority(Thread.MIN_PRIORITY);        this.setName(newHostAddress + "_" + newPort             + "_KickProcessIncomingMessage_" + counter);        counter++;    }    public void run()    {        try        {            processIncomingMessage(hostAddress, port, bu);        }        catch (java.io.IOException exc)        {            if (AsnObject.debug > 0)            {                System.out.println(getClass().getName() + ".run(): IOException: " + exc.getMessage());            }        }        catch (DecodingException exc)        {            if (AsnObject.debug > 1)            {                System.out.println(getClass().getName() + ".run(): DecodingException: " + exc.getMessage());            }        }    }}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -