summaryrefslogtreecommitdiff
path: root/org/apache/commons/net/tftp/TFTP.java
diff options
context:
space:
mode:
Diffstat (limited to 'org/apache/commons/net/tftp/TFTP.java')
-rw-r--r--org/apache/commons/net/tftp/TFTP.java301
1 files changed, 301 insertions, 0 deletions
diff --git a/org/apache/commons/net/tftp/TFTP.java b/org/apache/commons/net/tftp/TFTP.java
new file mode 100644
index 0000000..662da11
--- /dev/null
+++ b/org/apache/commons/net/tftp/TFTP.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.tftp;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.DatagramPacket;
+import java.net.SocketException;
+
+import org.apache.commons.net.DatagramSocketClient;
+
+/***
+ * The TFTP class exposes a set of methods to allow you to deal with the TFTP
+ * protocol directly, in case you want to write your own TFTP client or
+ * server. However, almost every user should only be concerend with
+ * the {@link org.apache.commons.net.DatagramSocketClient#open open() },
+ * and {@link org.apache.commons.net.DatagramSocketClient#close close() },
+ * methods. Additionally,the a
+ * {@link org.apache.commons.net.DatagramSocketClient#setDefaultTimeout setDefaultTimeout() }
+ * method may be of importance for performance tuning.
+ * <p>
+ * Details regarding the TFTP protocol and the format of TFTP packets can
+ * be found in RFC 783. But the point of these classes is to keep you
+ * from having to worry about the internals.
+ * <p>
+ * <p>
+ * @author Daniel F. Savarese
+ * @see org.apache.commons.net.DatagramSocketClient
+ * @see TFTPPacket
+ * @see TFTPPacketException
+ * @see TFTPClient
+ ***/
+
+public class TFTP extends DatagramSocketClient
+{
+ /***
+ * The ascii transfer mode. Its value is 0 and equivalent to NETASCII_MODE
+ ***/
+ public static final int ASCII_MODE = 0;
+
+ /***
+ * The netascii transfer mode. Its value is 0.
+ ***/
+ public static final int NETASCII_MODE = 0;
+
+ /***
+ * The binary transfer mode. Its value is 1 and equivalent to OCTET_MODE.
+ ***/
+ public static final int BINARY_MODE = 1;
+
+ /***
+ * The image transfer mode. Its value is 1 and equivalent to OCTET_MODE.
+ ***/
+ public static final int IMAGE_MODE = 1;
+
+ /***
+ * The octet transfer mode. Its value is 1.
+ ***/
+ public static final int OCTET_MODE = 1;
+
+ /***
+ * The default number of milliseconds to wait to receive a datagram
+ * before timing out. The default is 5000 milliseconds (5 seconds).
+ ***/
+ public static final int DEFAULT_TIMEOUT = 5000;
+
+ /***
+ * The default TFTP port according to RFC 783 is 69.
+ ***/
+ public static final int DEFAULT_PORT = 69;
+
+ /***
+ * The size to use for TFTP packet buffers. Its 4 plus the
+ * TFTPPacket.SEGMENT_SIZE, i.e. 516.
+ ***/
+ static final int PACKET_SIZE = TFTPPacket.SEGMENT_SIZE + 4;
+
+ /*** A buffer used to accelerate receives in bufferedReceive() ***/
+ private byte[] __receiveBuffer;
+
+ /*** A datagram used to minimize memory allocation in bufferedReceive() ***/
+ private DatagramPacket __receiveDatagram;
+
+ /*** A datagram used to minimize memory allocation in bufferedSend() ***/
+ private DatagramPacket __sendDatagram;
+
+ /***
+ * A buffer used to accelerate sends in bufferedSend().
+ * It is left package visible so that TFTPClient may be slightly more
+ * efficient during file sends. It saves the creation of an
+ * additional buffer and prevents a buffer copy in _newDataPcket().
+ ***/
+ byte[] _sendBuffer;
+
+
+ /***
+ * Returns the TFTP string representation of a TFTP transfer mode.
+ * Will throw an ArrayIndexOutOfBoundsException if an invalid transfer
+ * mode is specified.
+ * <p>
+ * @param mode The TFTP transfer mode. One of the MODE constants.
+ * @return The TFTP string representation of the TFTP transfer mode.
+ ***/
+ public static final String getModeName(int mode)
+ {
+ return TFTPRequestPacket._modeStrings[mode];
+ }
+
+ /***
+ * Creates a TFTP instance with a default timeout of DEFAULT_TIMEOUT,
+ * a null socket, and buffered operations disabled.
+ ***/
+ public TFTP()
+ {
+ setDefaultTimeout(DEFAULT_TIMEOUT);
+ __receiveBuffer = null;
+ __receiveDatagram = null;
+ }
+
+ /***
+ * This method synchronizes a connection by discarding all packets that
+ * may be in the local socket buffer. This method need only be called
+ * when you implement your own TFTP client or server.
+ * <p>
+ * @exception IOException if an I/O error occurs.
+ ***/
+ public final void discardPackets() throws IOException
+ {
+ int to;
+ DatagramPacket datagram;
+
+ datagram = new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);
+
+ to = getSoTimeout();
+ setSoTimeout(1);
+
+ try
+ {
+ while (true)
+ _socket_.receive(datagram);
+ }
+ catch (SocketException e)
+ {
+ // Do nothing. We timed out so we hope we're caught up.
+ }
+ catch (InterruptedIOException e)
+ {
+ // Do nothing. We timed out so we hope we're caught up.
+ }
+
+ setSoTimeout(to);
+ }
+
+
+ /***
+ * This is a special method to perform a more efficient packet receive.
+ * It should only be used after calling
+ * {@link #beginBufferedOps beginBufferedOps() }. beginBufferedOps()
+ * initializes a set of buffers used internally that prevent the new
+ * allocation of a DatagramPacket and byte array for each send and receive.
+ * To use these buffers you must call the bufferedReceive() and
+ * bufferedSend() methods instead of send() and receive(). You must
+ * also be certain that you don't manipulate the resulting packet in
+ * such a way that it interferes with future buffered operations.
+ * For example, a TFTPDataPacket received with bufferedReceive() will
+ * have a reference to the internal byte buffer. You must finish using
+ * this data before calling bufferedReceive() again, or else the data
+ * will be overwritten by the the call.
+ * <p>
+ * @return The TFTPPacket received.
+ * @exception InterruptedIOException If a socket timeout occurs. The
+ * Java documentation claims an InterruptedIOException is thrown
+ * on a DatagramSocket timeout, but in practice we find a
+ * SocketException is thrown. You should catch both to be safe.
+ * @exception SocketException If a socket timeout occurs. The
+ * Java documentation claims an InterruptedIOException is thrown
+ * on a DatagramSocket timeout, but in practice we find a
+ * SocketException is thrown. You should catch both to be safe.
+ * @exception IOException If some other I/O error occurs.
+ * @exception TFTPPacketException If an invalid TFTP packet is received.
+ ***/
+ public final TFTPPacket bufferedReceive() throws IOException,
+ InterruptedIOException, SocketException, TFTPPacketException
+ {
+ __receiveDatagram.setData(__receiveBuffer);
+ __receiveDatagram.setLength(__receiveBuffer.length);
+ _socket_.receive(__receiveDatagram);
+
+ return TFTPPacket.newTFTPPacket(__receiveDatagram);
+ }
+
+ /***
+ * This is a special method to perform a more efficient packet send.
+ * It should only be used after calling
+ * {@link #beginBufferedOps beginBufferedOps() }. beginBufferedOps()
+ * initializes a set of buffers used internally that prevent the new
+ * allocation of a DatagramPacket and byte array for each send and receive.
+ * To use these buffers you must call the bufferedReceive() and
+ * bufferedSend() methods instead of send() and receive(). You must
+ * also be certain that you don't manipulate the resulting packet in
+ * such a way that it interferes with future buffered operations.
+ * For example, a TFTPDataPacket received with bufferedReceive() will
+ * have a reference to the internal byte buffer. You must finish using
+ * this data before calling bufferedReceive() again, or else the data
+ * will be overwritten by the the call.
+ * <p>
+ * @param packet The TFTP packet to send.
+ * @exception IOException If some I/O error occurs.
+ ***/
+ public final void bufferedSend(TFTPPacket packet) throws IOException
+ {
+ _socket_.send(packet._newDatagram(__sendDatagram, _sendBuffer));
+ }
+
+
+ /***
+ * Initializes the internal buffers. Buffers are used by
+ * {@link #bufferedSend bufferedSend() } and
+ * {@link #bufferedReceive bufferedReceive() }. This
+ * method must be called before calling either one of those two
+ * methods. When you finish using buffered operations, you must
+ * call {@link #endBufferedOps endBufferedOps() }.
+ ***/
+ public final void beginBufferedOps()
+ {
+ __receiveBuffer = new byte[PACKET_SIZE];
+ __receiveDatagram =
+ new DatagramPacket(__receiveBuffer, __receiveBuffer.length);
+ _sendBuffer = new byte[PACKET_SIZE];
+ __sendDatagram =
+ new DatagramPacket(_sendBuffer, _sendBuffer.length);
+ }
+
+ /***
+ * Releases the resources used to perform buffered sends and receives.
+ ***/
+ public final void endBufferedOps()
+ {
+ __receiveBuffer = null;
+ __receiveDatagram = null;
+ _sendBuffer = null;
+ __sendDatagram = null;
+ }
+
+
+ /***
+ * Sends a TFTP packet to its destination.
+ * <p>
+ * @param packet The TFTP packet to send.
+ * @exception IOException If some I/O error occurs.
+ ***/
+ public final void send(TFTPPacket packet) throws IOException
+ {
+ _socket_.send(packet.newDatagram());
+ }
+
+
+ /***
+ * Receives a TFTPPacket.
+ * <p>
+ * @return The TFTPPacket received.
+ * @exception InterruptedIOException If a socket timeout occurs. The
+ * Java documentation claims an InterruptedIOException is thrown
+ * on a DatagramSocket timeout, but in practice we find a
+ * SocketException is thrown. You should catch both to be safe.
+ * @exception SocketException If a socket timeout occurs. The
+ * Java documentation claims an InterruptedIOException is thrown
+ * on a DatagramSocket timeout, but in practice we find a
+ * SocketException is thrown. You should catch both to be safe.
+ * @exception IOException If some other I/O error occurs.
+ * @exception TFTPPacketException If an invalid TFTP packet is received.
+ ***/
+ public final TFTPPacket receive() throws IOException, InterruptedIOException,
+ SocketException, TFTPPacketException
+ {
+ DatagramPacket packet;
+
+ packet = new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);
+
+ _socket_.receive(packet);
+
+ return TFTPPacket.newTFTPPacket(packet);
+ }
+
+
+}