tftp.java

来自「apache推出的net包」· Java 代码 · 共 299 行

JAVA
299
字号
/* * Copyright 2001-2005 The Apache Software Foundation * * Licensed 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);    }}

⌨️ 快捷键说明

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