CharGenUDPClient.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.net.chargen;

  18. import java.io.IOException;
  19. import java.net.DatagramPacket;
  20. import java.net.InetAddress;

  21. import org.apache.commons.net.DatagramSocketClient;
  22. import org.apache.commons.net.util.NetConstants;

  23. /**
  24.  * The CharGenUDPClient class is a UDP implementation of a client for the character generator protocol described in RFC 864. It can also be used for Systat (RFC
  25.  * 866), Quote of the Day (RFC 865), and netstat (port 15). All of these protocols involve sending a datagram to the appropriate port, and reading data
  26.  * contained in one or more reply datagrams. The chargen and quote of the day protocols only send one reply datagram containing 512 bytes or fewer. The
  27.  * other protocols may reply with more than one datagram, in which case you must wait for a timeout to determine that all reply datagrams have been sent.
  28.  * <p>
  29.  * To use the CharGenUDPClient class, just open a local UDP port with {@link org.apache.commons.net.DatagramSocketClient#open open } and call {@link #send send
  30.  * } to send the datagram that will initiate the data reply. For chargen or quote of the day, just call {@link #receive receive }, and you're done. For netstat
  31.  * and systat, call receive in a while loop, and catch a SocketException and InterruptedIOException to detect a timeout (don't forget to set the timeout
  32.  * duration beforehand). Don't forget to call {@link org.apache.commons.net.DatagramSocketClient#close close() } to clean up properly.
  33.  *
  34.  * @see CharGenTCPClient
  35.  */
  36. public final class CharGenUDPClient extends DatagramSocketClient {

  37.     /** The systat port value of 11 according to RFC 866. */
  38.     public static final int SYSTAT_PORT = 11;

  39.     /** The netstat port value of 19. */
  40.     public static final int NETSTAT_PORT = 15;

  41.     /** The quote of the day port value of 17 according to RFC 865. */
  42.     public static final int QUOTE_OF_DAY_PORT = 17;

  43.     /** The character generator port value of 19 according to RFC 864. */
  44.     public static final int CHARGEN_PORT = 19;

  45.     /** The default chargen port. It is set to 19 according to RFC 864. */
  46.     public static final int DEFAULT_PORT = 19;

  47.     private final byte[] receiveData;
  48.     private final DatagramPacket receivePacket;
  49.     private final DatagramPacket sendPacket;

  50.     /**
  51.      * The default CharGenUDPClient constructor. It initializes some internal data structures for sending and receiving the necessary datagrams for the chargen
  52.      * and related protocols.
  53.      */
  54.     public CharGenUDPClient() {
  55.         // CharGen return packets have a maximum length of 512
  56.         receiveData = new byte[512];
  57.         receivePacket = new DatagramPacket(receiveData, receiveData.length);
  58.         sendPacket = new DatagramPacket(NetConstants.EMPTY_BTYE_ARRAY, 0);
  59.     }

  60.     /**
  61.      * Receive the reply data from the server. This will always be 512 bytes or fewer. Chargen and quote of the day only return one packet. Netstat and systat
  62.      * require multiple calls to receive() with timeout detection.
  63.      *
  64.      * @return The reply data from the server.
  65.      * @throws IOException If an error occurs while receiving the datagram.
  66.      */
  67.     public byte[] receive() throws IOException {
  68.         final int length;
  69.         final byte[] result;

  70.         checkOpen().receive(receivePacket);

  71.         result = new byte[length = receivePacket.getLength()];
  72.         System.arraycopy(receiveData, 0, result, 0, length);

  73.         return result;
  74.     }

  75.     /**
  76.      * Same as <code>send(host, CharGenUDPClient.DEFAULT_PORT);</code>
  77.      *
  78.      * @param host the destination host
  79.      * @throws IOException on error
  80.      */
  81.     public void send(final InetAddress host) throws IOException {
  82.         send(host, DEFAULT_PORT);
  83.     }

  84.     /**
  85.      * Sends the data initiation datagram. This data in the packet is ignored by the server, and merely serves to signal that the server should send its reply.
  86.      *
  87.      * @param host The address of the server.
  88.      * @param port The port of the service.
  89.      * @throws IOException If an error occurs while sending the datagram.
  90.      */
  91.     public void send(final InetAddress host, final int port) throws IOException {
  92.         sendPacket.setAddress(host);
  93.         sendPacket.setPort(port);
  94.         checkOpen().send(sendPacket);
  95.     }

  96. }