FileDocCategorySizeDatePackage
SnmpSocket.javaAPI DocJava SE 5 API10842Fri Aug 26 14:55:06 BST 2005com.sun.jmx.snmp.daemon

SnmpSocket

public final class SnmpSocket extends Object implements Runnable
This class creates an SNMP Datagram Socket. This class has methods helpful to send SNMP inform request packets to an arbitrary port of a specified device. It also runs a thread that is devoted to receiving SNMP inform response on the socket.
A socket imposes an upper limit on size of inform response packet. Any packet which exceeds this limit is truncated. By default, this limit is {@link SnmpAdaptorServer#bufferSize}.

Fields Summary
private DatagramSocket
_socket
private SnmpResponseHandler
_dgramHdlr
private Thread
_sockThread
private byte[]
_buffer
private transient boolean
isClosing
int
_socketPort
int
responseBufSize
String
dbgTag
Constructors Summary
public SnmpSocket(SnmpResponseHandler rspHdlr, InetAddress addr, int bufferSize)
Creates a new SnmpSocket object.

param
rspHdlr A Datagram handler.
param
bufferSize The SNMP adaptor buffer size.
exception
SocketException A socket could not be created.

    
    // CONSTRUCTORS
    //-------------
    
                                  
             
        super();
        
        if (isTraceOn()) {
            trace("constructor", "Creating new SNMP datagram socket");
        }
    
        // TIME BOMB HERE
        _socket = new DatagramSocket(0, addr);
        _socketPort = _socket.getLocalPort();
        responseBufSize = bufferSize;
        _buffer = new byte[responseBufSize];
        _dgramHdlr = rspHdlr;
        _sockThread = new Thread(this, "SnmpSocket");
        _sockThread.start();
    
Methods Summary
public synchronized voidclose()
Closes the socket and its associated resources.

        
        isClosing = true;

        if (isTraceOn()) {
            trace("close", "Closing and destroying the SNMP datagram socket -> " + toString());
        }
        
        try {
            // We send an empty datagram packet to fix bug 4293791 (it's a jdk 1.1 bug)
            //
            DatagramSocket sn = new java.net.DatagramSocket(0);
            byte[] ob = new byte[1];
            DatagramPacket pk = new DatagramPacket(ob , 1, java.net.InetAddress.getLocalHost(), _socketPort);
            sn.send(pk);
            sn.close();
        } catch (Exception e) {}
                
        // First close the datagram socket.
        // This may generates an IO exception at the run method (_socket.receive).
        //
        if (_socket != null) {
            _socket.close() ;
            _socket = null ;
        }
    
        // Then stop the thread socket.
        //
        if (_sockThread != null && _sockThread.isAlive()) {
            _sockThread.interrupt();
            try {
                // Wait until the thread die.
                //
                _sockThread.join();
            } catch (InterruptedException e) {
                // Ignore...
            }
            _sockThread = null ;
        }
    
voiddebug(java.lang.String clz, java.lang.String func, java.lang.String info)

        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, clz, func, info);
    
voiddebug(java.lang.String clz, java.lang.String func, java.lang.Throwable exception)

        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP, clz, func, exception);
    
voiddebug(java.lang.String func, java.lang.String info)

        debug(dbgTag, func, info);
    
voiddebug(java.lang.String func, java.lang.Throwable exception)

        debug(dbgTag, func, exception);
    
public synchronized voidfinalize()
Finalizer of the SnmpSocket objects. This method is called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

Closes the datagram socket and stops the socket thread associated to this SNMP socket.

        close();
    
private synchronized voidhandleDatagram(java.net.DatagramPacket dgrmpkt)

        _dgramHdlr.processDatagram(dgrmpkt);
    
private synchronized voidhandleJavaError(java.lang.Throwable thr)

        if (thr instanceof OutOfMemoryError) {
            if (isDebugOn()) {
                debug("handleJavaError", thr);
            }
            Thread.currentThread().yield();
            return ;
        }
        if (_socket != null) {
            _socket.close();
            _socket = null;
        }

        if (isDebugOn()) {
            debug("handleJavaError", "Global Internal error");
        }
        Thread.currentThread().yield();
    
booleanisDebugOn()

        return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP);
    
booleanisTraceOn()

        return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP);
    
public synchronized booleanisValid()
Checks if the socket is initialised correctly and if it is still active.

return
true if the socket is initialised correctly and if it is still active, false otherwise.

        return _socket != null && _sockThread != null && _sockThread.isAlive();
    
public voidrun()
Dispatcher method for this socket thread. This is the dispatcher method which goes in an endless-loop and waits for receiving datagram packets on the socket.

        Thread.currentThread().setPriority(8);

        while (true) {
            try {
                DatagramPacket dgrmpkt = new DatagramPacket (_buffer, _buffer.length);

                if (isTraceOn()) {
                    trace("run", "[" + Thread.currentThread().toString() + "]:" + "Blocking for receiving packet");
                }

                _socket.receive(dgrmpkt);
                
                // If the corresponding session is being destroyed, stop handling received responses.
                //
                if (isClosing)
                    break;

                if (isTraceOn()) {
                    trace("run", "[" + Thread.currentThread().toString() + "]:" + "Received a packet");
                }

                if (dgrmpkt.getLength() <= 0)
                    continue;

                if (isTraceOn()) {
                    trace("run", "[" + Thread.currentThread().toString() + "]:" + "Received a packet from : " + 
                          dgrmpkt.getAddress().toString() + ", Length = " + dgrmpkt.getLength());
                }

                handleDatagram(dgrmpkt);
                
                // We are closing the snmp socket while handling the datagram.
                //
                if (isClosing)
                    break;
			
            } catch (IOException io) {
                // If the IO exception has been generated because of closing this SNMP socket,
                // (call to _socket.close while _socket is blocked for receiving packet) simply terminate closing properly.
                //
                if (isClosing) {
                    break;
                }
                if (isDebugOn()) {
                    debug("run", io.getMessage());
                    debug("run", io);
                }
            } catch (Exception e) {
                // If the exception (NullPointerException) has been generated because of closing this SNMP socket,
                // (call to _socket = null while _socket is blocked for receiving packet) simply terminate closing properly.
                //
                if (isClosing) {
                    break;
                }
                if (isDebugOn()) {
                    debug("run", "Exception in socket thread...");
                    debug("run", e);
                }
            } catch (ThreadDeath d) {
                if (isDebugOn()) {
                    debug("run", "Socket Thread DEAD..." + toString());
                    debug("run", d);
                }
                close();
                throw d;  // rethrow dead thread.
            } catch (Error err) {
                if (isDebugOn()) {
                    debug("run", err);
                }
                handleJavaError(err);
            }
        }
    
public synchronized voidsendPacket(byte[] buff, int length, java.net.InetAddress addr, int port)
Sends a datagram packet to a specified device at specified port.

param
buff The packet data.
param
length The packet length.
param
addr The destination address.
param
port The destination port number.
exception
IOException Signals that an I/O exception of some sort has occurred.

        DatagramPacket dgrmpkt;
        dgrmpkt = new DatagramPacket(buff, length, addr, port);
        sendPacket(dgrmpkt);
    
public synchronized voidsendPacket(java.net.DatagramPacket dgrmpkt)
Sends a datagram packet to a specified device at specified port.

param
dgrmpkt The datagram packet.
exception
IOException Signals that an I/O exception of some sort has occurred.

	
        try {
            if (isValid()) {
                if (isTraceOn()) {
                    trace("sendPacket", "Sending DatagramPacket. Length = " + dgrmpkt.getLength() +
                          " through socket = " + _socket.toString());
                }
                _socket.send(dgrmpkt);
            } else
                throw new IOException("Invalid state of SNMP datagram socket.");
        } catch (IOException e) {
            if (isDebugOn()) {
                debug("sendPacket", "Io error while sending");
                debug("sendPacket", e.getMessage());
            }
            throw e;
        } 
    
voidtrace(java.lang.String clz, java.lang.String func, java.lang.String info)

        Trace.send(Trace.LEVEL_TRACE, Trace.INFO_ADAPTOR_SNMP, clz, func, info);
    
voidtrace(java.lang.String func, java.lang.String info)

        trace(dbgTag, func, info);