client.java

来自「opennms得相关源码 请大家看看」· Java 代码 · 共 344 行

JAVA
344
字号
//// This file is part of the OpenNMS(R) Application.//// OpenNMS(R) is Copyright (C) 2002-2003 The OpenNMS Group, Inc.  All rights reserved.// OpenNMS(R) is a derivative work, containing both original code, included code and modified// code that was published under the GNU General Public License. Copyrights for modified // and included code are below.//// OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.//// Modifications://// 2003 Jan 31: Cleaned up some unused imports.//// Original code base Copyright (C) 1999-2001 Oculan Corp.  All rights reserved.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.                                                            //// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//       // For more information contact: //      OpenNMS Licensing       <license@opennms.org>//      http://www.opennms.org///      http://www.opennms.com///// Tab Stop = 8//package org.opennms.netmgt.dhcpd;import java.io.IOException;import java.io.InterruptedIOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.Socket;import java.net.UnknownHostException;import java.util.Observable;import org.apache.log4j.Category;import org.opennms.core.fiber.Fiber;import org.opennms.core.utils.ThreadCategory;import edu.bucknell.net.JDHCP.DHCPMessage;final class Client extends Observable implements Runnable, Fiber {    private final static short DHCP_TARGET_PORT = 67;    private static InetAddress NULL_ADDR;    private DatagramSocket m_sender;    private Socket m_client;    private ObjectOutputStream m_objsOut;    private String m_name;    private int m_status;    private Thread m_worker;    private UnicastListener m_unicastListener;    private boolean m_keepListening;    static {        try {            NULL_ADDR = InetAddress.getByName("0.0.0.0");        } catch (UnknownHostException uhE) {            throw new RuntimeException(uhE.getMessage());        }    }    /**     * The remote DHCP server we sent the request to has the option of either     * unicasting the response directly back to us or broadcasting the response     * to port 68 on the local subnet. The Receiver class handles the broadcast     * scenario and this class will take care of the unicast scenario.     */    public final class UnicastListener extends Thread {        /**         * Udp connection over which unicast DHCP response will be received.         */        DatagramSocket m_incomingUdp;        /**         * Client where any received responses will be forwarded.         */        Client m_client;        /**         * Constructor         *          * @param incoming         *            UDP socket over which the DHCP request was sent         * @param client         *            The client to which any unicasted responses are to be         *            forwarded         */        public UnicastListener(DatagramSocket incoming, Client client) {            super("UnicastListener-UDP-" + incoming.getLocalPort());            ThreadCategory.getInstance(this.getClass()).debug("constructing UnicastListener-UDP-" + incoming.getLocalPort());            m_incomingUdp = incoming;            m_client = client;        }        /**         * Does the work of the thread. Listens for unicasted responses from the         * DHCP server. If a response is received it will be forwarded to the         * client which requested that the DHCP request be generated.         */        public void run() {            Category log = ThreadCategory.getInstance(this.getClass());            if (log.isDebugEnabled())                log.debug("thread " + this.getName() + " running...");            // set socket timeout to 1 second so the value of m_keepListening            // can be checked periodically            try {                m_incomingUdp.setSoTimeout(1000);            } catch (IOException ioE) {                log.error("UnicastListener.run: unable to set socket timeout, reason: " + ioE.getLocalizedMessage());                log.debug(ioE);                m_keepListening = true;            }            // According to RFC 2131 a DHCP client must be prepared to receive a            // DHCP message up to 576 bytes. Although larger messages can            // be negotiated between the DHCP client and server if desired.            //            // Allocating a 2k buffer which should be more than sufficient.            // Any incoming packet larger than this size will cause an            // arrayOutOfBoundsException to be generated, in that case an            // error message will be logged and the packet will be discarded.            //            byte[] dgbuf = new byte[2048];            // Wait for any incoming unicast responses.            //            while (m_keepListening) {                try {                    DatagramPacket pkt = new DatagramPacket(dgbuf, dgbuf.length);                    m_incomingUdp.receive(pkt);                    Message msg = new Message(pkt.getAddress(), new DHCPMessage(pkt.getData()));                    try {                        m_client.sendMessage(msg);                    } catch (IOException ex) {                        log.warn("Error sending unicast response to client " + m_client.getName());                    }                } catch (InterruptedIOException ex) {                    // Check exit flag                    continue;                } catch (ArrayIndexOutOfBoundsException oobE) {                    // Packet was too large for buffer...log and discard                    log.debug("UnicastListener.run: array out of bounds exception.", oobE);                    log.warn("UnicastListener.run: malformed DHCP packet, packet too large for buffer (buffer sz=" + dgbuf.length + "), discarding packet.");                } catch (IOException ioE) {                    log.error("UnicastListener.run: io exception receiving response", ioE);                    m_keepListening = false;                } catch (Exception E) {                    log.error("UnicastListener.run: exception receiving response", E);                    m_keepListening = false;                }            }            if (log.isDebugEnabled())                log.debug("thread " + this.getName() + " exiting...");        }    }    Client(Socket clnt) throws IOException {        m_name = "DHCPClient-TCP-" + clnt.getPort();        m_client = clnt;        m_worker = null;        m_status = START_PENDING;        m_sender = new DatagramSocket();        // Construct UnicastListener thread which will receive the        // DHCP response if the remote DHCP server unicasts the response        // directly back over the outgoing Datagram Socket        //        ThreadCategory.getInstance(this.getClass()).debug("Client.ctor: outgoing udp socket port: " + m_sender.getLocalPort());        m_unicastListener = new UnicastListener(m_sender, this);        m_keepListening = true;        m_objsOut = new ObjectOutputStream(m_client.getOutputStream());        m_objsOut.reset();        m_objsOut.flush();    }    void sendMessage(Message msg) throws IOException {        m_objsOut.writeObject(msg);        m_objsOut.flush();    }    public synchronized void start() {        if (m_worker != null)            throw new IllegalStateException("The fiber has already been started");        // Start UnicastListener thread.        //        m_unicastListener.start();        m_worker = new Thread(this, getName());        m_worker.setDaemon(true);        m_worker.start();        m_status = STARTING;    }    public synchronized void stop() {        m_status = STOP_PENDING;        try {            m_objsOut.close();            m_client.close();        } catch (IOException ex) {        }        m_sender.close();        m_worker.interrupt();    }    public synchronized int getStatus() {        return m_status;    }    public String getName() {        return m_name;    }    public void run() {        Category log = ThreadCategory.getInstance(this.getClass());        boolean isOk = true;        // get the input stream as a object stream        //        ObjectInputStream input = null;        try {            input = new ObjectInputStream(m_client.getInputStream());        } catch (IOException ex) {            log.warn("Failed to read client's input stream", ex);            isOk = false;        }        // set the state        //        if (isOk) {            synchronized (this) {                m_status = RUNNING;            }        }        // Roundy, Roundy, Round we go...        //        while (isOk && m_status == RUNNING) {            try {                Message msg = (Message) input.readObject();                if (msg.getAddress().equals(NULL_ADDR)) {                    if (log.isDebugEnabled())                        log.debug("Got disconnect request from Poller corresponding to sending port " + m_sender.getLocalPort());                    isOk = false;                } else {                    if (log.isDebugEnabled())                        log.debug("Got request... adress = " + msg.getAddress());                    byte[] dhcp = msg.getMessage().externalize();                    DatagramPacket pkt = new DatagramPacket(dhcp, dhcp.length, msg.getAddress(), DHCP_TARGET_PORT);                    try {                        if (log.isDebugEnabled())                           log.debug("sending request on port: " + m_sender.getLocalPort());                        m_sender.send(pkt);                    } catch (IOException ex) {                    } // discard                }            } catch (ClassNotFoundException ex) {                log.warn("Failed to read message, no class found", ex);                isOk = false;            } catch (IOException ex) {                log.warn("Failed to read message, I/O error", ex);                isOk = false;            } catch (ClassCastException ex) {                log.warn("Failed to read an appropriate message", ex);                isOk = false;            } catch (Throwable t) {                log.warn("Undeclared throwable caught", t);                isOk = false;            }        }        synchronized (this) {            m_status = STOP_PENDING;        }        // stop the unicast listener thread and wait for it to exit        //        m_keepListening = false;        if (log.isDebugEnabled())            log.debug("run: waiting for UnicastListener thread " + this.getName() + " to die...");        try {            m_unicastListener.join();        } catch (InterruptedException e) {            log.debug("run: interrupted while waiting for UnicastListener thread " + this.getName() + " to die", e);        }        if (log.isDebugEnabled())            log.debug("run: UnicastListener thread " + this.getName() + " is dead...");        // close the datagram socket        //        m_sender.close();        // close the client's socket        //        try {            input.close();            m_client.close();        } catch (IOException e) {        }        // Notify        //        notifyObservers();        synchronized (this) {            m_status = STOPPED;        }    } // end run() method}

⌨️ 快捷键说明

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