Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * 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  org.apache.commons.net.io.FromNetASCIIOutputStream;
 import  org.apache.commons.net.io.ToNetASCIIInputStream;

The TFTPClient class encapsulates all the aspects of the TFTP protocol necessary to receive and send files through TFTP. It is derived from the org.apache.commons.net.tftp.TFTP because it is more convenient than using aggregation, and as a result exposes the same set of methods to allow you to deal with the TFTP protocol directly. However, almost every user should only be concerend with the the open() , close() , sendFile() , and receiveFile() methods. Additionally, the setMaxTimeouts() and setDefaultTimeout() methods 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.

See also:
TFTP
TFTPPacket
TFTPPacketException
 
 
 public class TFTPClient extends TFTP
 {
    
The default number of times a receive attempt is allowed to timeout before ending attempts to retry the receive and failing. The default is 5 timeouts.
 
     public static final int DEFAULT_MAX_TIMEOUTS = 5;

    
The maximum number of timeouts allowed before failing. *
 
     private int __maxTimeouts;

    
Creates a TFTPClient instance with a default timeout of DEFAULT_TIMEOUT, maximum timeouts value of DEFAULT_MAX_TIMEOUTS, a null socket, and buffered operations disabled.
 
     public TFTPClient()
     {
          = ;
     }

    
Sets the maximum number of times a receive attempt is allowed to timeout during a receiveFile() or sendFile() operation before ending attempts to retry the receive and failing. The default is DEFAULT_MAX_TIMEOUTS.

Parameters:
numTimeouts The maximum number of timeouts to allow. Values less than 1 should not be used, but if they are, they are treated as 1.
 
     public void setMaxTimeouts(int numTimeouts)
     {
         if (numTimeouts < 1) {
              = 1;
         } else {
              = numTimeouts;
         }
     }

    
Returns the maximum number of times a receive attempt is allowed to timeout before ending attempts to retry the receive and failing.

Returns:
The maximum number of timeouts allowed.
    public int getMaxTimeouts()
    {
        return ;
    }


    
Requests a named file from a remote host, writes the file to an OutputStream, closes the connection, and returns the number of bytes read. A local UDP socket must first be created by open() before invoking this method. This method will not close the OutputStream containing the file; you must close it after the method invocation.

Parameters:
filename The name of the file to receive.
mode The TFTP mode of the transfer (one of the MODE constants).
output The OutputStream to which the file should be written.
host The remote host serving the file.
port The port number of the remote TFTP server.
Throws:
IOException If an I/O error occurs. The nature of the error will be reported in the message.
    public int receiveFile(String filenameint modeOutputStream output,
                           InetAddress hostint portthrows IOException
    {
        int bytesReadtimeoutslastBlockblockhostPortdataLength;
        TFTPPacket sentreceived = null;
        TFTPErrorPacket error;
        TFTPDataPacket data;
        TFTPAckPacket ack = new TFTPAckPacket(hostport, 0);
        beginBufferedOps();
        dataLength = lastBlock = hostPort = bytesRead = 0;
        block = 1;
        if (mode == .) {
            output = new FromNetASCIIOutputStream(output);
        }
        sent =
            new TFTPReadRequestPacket(hostportfilenamemode);
_sendPacket:
        do
        {
            bufferedSend(sent);
_receivePacket:
            while (true)
            {
                timeouts = 0;
                do {
                    try
                    {
                        received = bufferedReceive();
                        break;
                    }
                    catch (SocketException e)
                    {
                        if (++timeouts >= )
                        {
                            endBufferedOps();
                            throw new IOException("Connection timed out.");
                        }
                        continue _sendPacket;
                    }
                    catch (InterruptedIOException e)
                    {
                        if (++timeouts >= )
                        {
                            endBufferedOps();
                            throw new IOException("Connection timed out.");
                        }
                        continue _sendPacket;
                    }
                    catch (TFTPPacketException e)
                    {
                        endBufferedOps();
                        throw new IOException("Bad packet: " + e.getMessage());
                    }
                } while (timeouts < ); // __maxTimeouts >=1 so will always do loop at least once
                // The first time we receive we get the port number and
                // answering host address (for hosts with multiple IPs)
                if (lastBlock == 0)
                {
                    hostPort = received.getPort();
                    ack.setPort(hostPort);
                    if(!host.equals(received.getAddress()))
                    {
                        host = received.getAddress();
                        ack.setAddress(host);
                        sent.setAddress(host);
                    }
                }
                // Comply with RFC 783 indication that an error acknowledgment
                // should be sent to originator if unexpected TID or host.
                if (host.equals(received.getAddress()) &&
                        received.getPort() == hostPort)
                {
                    switch (received.getType())
                    {
                    case .:
                        error = (TFTPErrorPacket)received;
                        endBufferedOps();
                        throw new IOException("Error code " + error.getError() +
                                              " received: " + error.getMessage());
                    case .:
                        data = (TFTPDataPacket)received;
                        dataLength = data.getDataLength();
                        lastBlock = data.getBlockNumber();
                        if (lastBlock == block)
                        {
                            try
                            {
                                output.write(data.getData(), data.getDataOffset(),
                                             dataLength);
                            }
                            catch (IOException e)
                            {
                                error = new TFTPErrorPacket(hosthostPort,
                                                            .,
                                                            "File write failed.");
                                bufferedSend(error);
                                endBufferedOps();
                                throw e;
                            }
                            ++block;
                            if (block > 65535)
                            {
                                // wrap the block number
                                block = 0;
                            }
                            break _receivePacket;
                        }
                        else
                        {
                            discardPackets();
                            if (lastBlock == (block == 0 ? 65535 : (block - 1))) {
                                continue _sendPacket;  // Resend last acknowledgement.
                            }
                            continue _receivePacket; // Start fetching packets again.
                        }
                        //break;
                    default:
                        endBufferedOps();
                        throw new IOException("Received unexpected packet type.");
                    }
                }
                else
                {
                    error = new TFTPErrorPacket(received.getAddress(),
                                                received.getPort(),
                                                .,
                                                "Unexpected host or port.");
                    bufferedSend(error);
                    continue _sendPacket;
                }
                // We should never get here, but this is a safety to avoid
                // infinite loop.  If only Java had the goto statement.
                //break;
            }
            ack.setBlockNumber(lastBlock);
            sent = ack;
            bytesRead += dataLength;
        } // First data packet less than 512 bytes signals end of stream.
        while (dataLength == .);
        bufferedSend(sent);
        endBufferedOps();
        return bytesRead;
    }


    
Requests a named file from a remote host, writes the file to an OutputStream, closes the connection, and returns the number of bytes read. A local UDP socket must first be created by open() before invoking this method. This method will not close the OutputStream containing the file; you must close it after the method invocation.

Parameters:
filename The name of the file to receive.
mode The TFTP mode of the transfer (one of the MODE constants).
output The OutputStream to which the file should be written.
hostname The name of the remote host serving the file.
port The port number of the remote TFTP server.
Throws:
IOException If an I/O error occurs. The nature of the error will be reported in the message.
UnknownHostException If the hostname cannot be resolved.
    public int receiveFile(String filenameint modeOutputStream output,
                           String hostnameint port)
    {
        return receiveFile(filenamemodeoutput, InetAddress.getByName(hostname),
                           port);
    }


    
Same as calling receiveFile(filename, mode, output, host, TFTP.DEFAULT_PORT).

Parameters:
filename The name of the file to receive.
mode The TFTP mode of the transfer (one of the MODE constants).
output The OutputStream to which the file should be written.
host The remote host serving the file.
Throws:
IOException If an I/O error occurs. The nature of the error will be reported in the message.
    public int receiveFile(String filenameint modeOutputStream output,
                           InetAddress host)
    throws IOException
    {
        return receiveFile(filenamemodeoutputhost);
    }

    
Same as calling receiveFile(filename, mode, output, hostname, TFTP.DEFAULT_PORT).

Parameters:
filename The name of the file to receive.
mode The TFTP mode of the transfer (one of the MODE constants).
output The OutputStream to which the file should be written.
hostname The name of the remote host serving the file.
Throws:
IOException If an I/O error occurs. The nature of the error will be reported in the message.
UnknownHostException If the hostname cannot be resolved.
    public int receiveFile(String filenameint modeOutputStream output,
                           String hostname)
    {
        return receiveFile(filenamemodeoutput, InetAddress.getByName(hostname),
                           );
    }


    
Requests to send a file to a remote host, reads the file from an InputStream, sends the file to the remote host, and closes the connection. A local UDP socket must first be created by open() before invoking this method. This method will not close the InputStream containing the file; you must close it after the method invocation.

Parameters:
filename The name the remote server should use when creating the file on its file system.
mode The TFTP mode of the transfer (one of the MODE constants).
host The remote host receiving the file.
port The port number of the remote TFTP server.
Throws:
IOException If an I/O error occurs. The nature of the error will be reported in the message.
    public void sendFile(String filenameint modeInputStream input,
                         InetAddress hostint portthrows IOException
    {
        int bytesReadtimeoutslastBlockblockhostPortdataLengthoffsettotalThisPacket;
        TFTPPacket sentreceived = null;
        TFTPErrorPacket error;
        TFTPDataPacket data =
            new TFTPDataPacket(hostport, 0, , 4, 0);
        TFTPAckPacket ack;
        boolean justStarted = true;
        beginBufferedOps();
        dataLength = lastBlock = hostPort = bytesRead = totalThisPacket = 0;
        block = 0;
        boolean lastAckWait = false;
        if (mode == .) {
            input = new ToNetASCIIInputStream(input);
        }
        sent =
            new TFTPWriteRequestPacket(hostportfilenamemode);
_sendPacket:
        do
        {
            // first time: block is 0, lastBlock is 0, send a request packet.
            // subsequent: block is integer starting at 1, send data packet.
            bufferedSend(sent);
            // this is trying to receive an ACK
_receivePacket:
            while (true)
            {
                timeouts = 0;
                do {
                    try
                    {
                        received = bufferedReceive();
                        break;
                    }
                    catch (SocketException e)
                    {
                        if (++timeouts >= )
                        {
                            endBufferedOps();
                            throw new IOException("Connection timed out.");
                        }
                        continue _sendPacket;
                    }
                    catch (InterruptedIOException e)
                    {
                        if (++timeouts >= )
                        {
                            endBufferedOps();
                            throw new IOException("Connection timed out.");
                        }
                        continue _sendPacket;
                    }
                    catch (TFTPPacketException e)
                    {
                        endBufferedOps();
                        throw new IOException("Bad packet: " + e.getMessage());
                    }
                } // end of while loop over tries to receive
                while (timeouts < ); // __maxTimeouts >=1 so will always do loop at least once
                // The first time we receive we get the port number and
                // answering host address (for hosts with multiple IPs)
                if (justStarted)
                {
                    justStarted = false;
                    hostPort = received.getPort();
                    data.setPort(hostPort);
                    if(!host.equals(received.getAddress()))
                    {
                        host = received.getAddress();
                        data.setAddress(host);
                        sent.setAddress(host);
                    }
                }
                // Comply with RFC 783 indication that an error acknowledgment
                // should be sent to originator if unexpected TID or host.
                if (host.equals(received.getAddress()) &&
                        received.getPort() == hostPort)
                {
                    switch (received.getType())
                    {
                    case .:
                        error = (TFTPErrorPacket)received;
                        endBufferedOps();
                        throw new IOException("Error code " + error.getError() +
                                              " received: " + error.getMessage());
                    case .:
                        ack = (TFTPAckPacket)received;
                        lastBlock = ack.getBlockNumber();
                        if (lastBlock == block)
                        {
                            ++block;
                            if (block > 65535)
                            {
                                // wrap the block number
                                block = 0;
                            }
                            if (lastAckWait) {
                              break _sendPacket;
                            }
                            else {
                              break _receivePacket;
                            }
                        }
                        else
                        {
                            discardPackets();
                            continue _receivePacket; // Start fetching packets again.
                        }
                        //break;
                    default:
                        endBufferedOps();
                        throw new IOException("Received unexpected packet type.");
                    }
                }
                else
                {
                    error = new TFTPErrorPacket(received.getAddress(),
                                                received.getPort(),
                                                .,
                                                "Unexpected host or port.");
                    bufferedSend(error);
                    continue _sendPacket;
                }
                // We should never get here, but this is a safety to avoid
                // infinite loop.  If only Java had the goto statement.
                //break;
            }
            // OK, we have just gotten ACK about the last data we sent. Make another
            // and send it
            dataLength = .;
            offset = 4;
            totalThisPacket = 0;
            while (dataLength > 0 &&
                    (bytesRead = input.read(offsetdataLength)) > 0)
            {
                offset += bytesRead;
                dataLength -= bytesRead;
                totalThisPacket += bytesRead;
            }
            iftotalThisPacket < . ) {
                /* this will be our last packet -- send, wait for ack, stop */
                lastAckWait = true;
            }
            data.setBlockNumber(block);
            data.setData(, 4, totalThisPacket);
            sent = data;
        }
        while ( totalThisPacket > 0 || lastAckWait );
        // Note: this was looping while dataLength == 0 || lastAckWait,
        // which was discarding the last packet if it was not full size
        // Should send the packet.
        endBufferedOps();
    }


    
Requests to send a file to a remote host, reads the file from an InputStream, sends the file to the remote host, and closes the connection. A local UDP socket must first be created by open() before invoking this method. This method will not close the InputStream containing the file; you must close it after the method invocation.

Parameters:
filename The name the remote server should use when creating the file on its file system.
mode The TFTP mode of the transfer (one of the MODE constants).
hostname The name of the remote host receiving the file.
port The port number of the remote TFTP server.
Throws:
IOException If an I/O error occurs. The nature of the error will be reported in the message.
UnknownHostException If the hostname cannot be resolved.
    public void sendFile(String filenameint modeInputStream input,
                         String hostnameint port)
    {
        sendFile(filenamemodeinput, InetAddress.getByName(hostname), port);
    }


    
Same as calling sendFile(filename, mode, input, host, TFTP.DEFAULT_PORT).

Parameters:
filename The name the remote server should use when creating the file on its file system.
mode The TFTP mode of the transfer (one of the MODE constants).
host The name of the remote host receiving the file.
Throws:
IOException If an I/O error occurs. The nature of the error will be reported in the message.
UnknownHostException If the hostname cannot be resolved.
    public void sendFile(String filenameint modeInputStream input,
                         InetAddress host)
    throws IOException
    {
        sendFile(filenamemodeinputhost);
    }

    
Same as calling sendFile(filename, mode, input, hostname, TFTP.DEFAULT_PORT).

Parameters:
filename The name the remote server should use when creating the file on its file system.
mode The TFTP mode of the transfer (one of the MODE constants).
hostname The name of the remote host receiving the file.
Throws:
IOException If an I/O error occurs. The nature of the error will be reported in the message.
UnknownHostException If the hostname cannot be resolved.
    public void sendFile(String filenameint modeInputStream input,
                         String hostname)
    {
        sendFile(filenamemodeinput, InetAddress.getByName(hostname),
                 );
    }
New to GrepCode? Check out our FAQ X