001    /*
002     * Copyright 2001-2005 The Apache Software Foundation
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.apache.commons.net;
017    
018    import java.io.IOException;
019    import java.net.DatagramPacket;
020    import java.net.InetAddress;
021    
022    /***
023     * The CharGenUDPClient class is a UDP implementation of a client for the
024     * character generator protocol described in RFC 864.  It can also be
025     * used for Systat (RFC 866), Quote of the Day (RFC 865), and netstat
026     * (port 15).  All of these protocols involve sending a datagram to the
027     * appropriate port, and reading data contained in one or more reply
028     * datagrams.  The chargen and quote of the day protocols only send
029     * one reply datagram containing 512 bytes or less of data.  The other
030     * protocols may reply with more than one datagram, in which case you
031     * must wait for a timeout to determine that all reply datagrams have
032     * been sent.
033     * <p>
034     * To use the CharGenUDPClient class, just open a local UDP port
035     * with {@link org.apache.commons.net.DatagramSocketClient#open  open }
036     * and call {@link #send  send } to send the datagram that will
037     * initiate the data reply.  For chargen or quote of the day, just
038     * call {@link #receive  receive }, and you're done.  For netstat and
039     * systat, call receive in a while loop, and catch a SocketException and
040     * InterruptedIOException to detect a timeout (don't forget to set the
041     * timeout duration beforehand).  Don't forget to call
042     * {@link org.apache.commons.net.DatagramSocketClient#close  close() }
043     * to clean up properly.
044     * <p>
045     * <p>
046     * @author Daniel F. Savarese
047     * @see CharGenTCPClient
048     ***/
049    
050    public final class CharGenUDPClient extends DatagramSocketClient
051    {
052        /*** The systat port value of 11 according to RFC 866. ***/
053        public static final int SYSTAT_PORT = 11;
054        /*** The netstat port value of 19. ***/
055        public static final int NETSTAT_PORT = 15;
056        /*** The quote of the day port value of 17 according to RFC 865. ***/
057        public static final int QUOTE_OF_DAY_PORT = 17;
058        /*** The character generator port value of 19 according to RFC 864. ***/
059        public static final int CHARGEN_PORT = 19;
060        /*** The default chargen port.  It is set to 19 according to RFC 864. ***/
061        public static final int DEFAULT_PORT = 19;
062    
063        private byte[] __receiveData;
064        private DatagramPacket __receivePacket;
065        private DatagramPacket __sendPacket;
066    
067        /***
068         * The default CharGenUDPClient constructor.  It initializes some internal
069         * data structures for sending and receiving the necessary datagrams for
070         * the chargen and related protocols.
071         ***/
072        public CharGenUDPClient()
073        {
074            // CharGen return packets have a maximum length of 512
075            __receiveData = new byte[512];
076            __receivePacket = new DatagramPacket(__receiveData, 512);
077            __sendPacket = new DatagramPacket(new byte[0], 0);
078        }
079    
080    
081        /***
082         * Sends the data initiation datagram.  This data in the packet is ignored
083         * by the server, and merely serves to signal that the server should send
084         * its reply.
085         * <p>
086         * @param host The address of the server.
087         * @param port The port of the service.
088         * @exception IOException If an error occurs while sending the datagram.
089         ***/
090        public void send(InetAddress host, int port) throws IOException
091        {
092            __sendPacket.setAddress(host);
093            __sendPacket.setPort(port);
094            _socket_.send(__sendPacket);
095        }
096    
097        /*** Same as <code>send(host, CharGenUDPClient.DEFAULT_PORT);</code> ***/
098        public void send(InetAddress host) throws IOException
099        {
100            send(host, DEFAULT_PORT);
101        }
102    
103        /***
104         * Receive the reply data from the server.  This will always be 512 bytes
105         * or less.  Chargen and quote of the day only return one packet.  Netstat
106         * and systat require multiple calls to receive() with timeout detection.
107         * <p>
108         * @return The reply data from the server.
109         * @exception IOException If an error occurs while receiving the datagram.
110         ***/
111        public byte[] receive() throws IOException
112        {
113            int length;
114            byte[] result;
115    
116            _socket_.receive(__receivePacket);
117    
118            result = new byte[length = __receivePacket.getLength()];
119            System.arraycopy(__receiveData, 0, result, 0, length);
120    
121            return result;
122        }
123    
124    }
125