From 063284837c8c366e5502b1b0264b8eb807b61732 Mon Sep 17 00:00:00 2001 From: Joe Robinson Date: Wed, 27 Oct 2010 14:21:09 +0100 Subject: Basic upload functionality to predifined location, with basic file browser --- org/apache/commons/net/tftp/TFTP.java | 301 ++++++++++++++++++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 org/apache/commons/net/tftp/TFTP.java (limited to 'org/apache/commons/net/tftp/TFTP.java') 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. + *

+ * 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. + *

+ *

+ * @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. + *

+ * @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. + *

+ * @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. + *

+ * @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. + *

+ * @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. + *

+ * @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. + *

+ * @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); + } + + +} -- cgit v1.2.3