|
LCM Software TFTP Package v1.5 |
|||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectcom.lcmsoft.tftp.TftpRequest
public class TftpRequest
Represents a TFTP request. It is the fundamental building block to implement
both TFTP servers and TFTP clients. That is because TftpRequest
can represent both requests to be sent to servers (used to implement TFTP
clients) and requests received from clients (used to implement TFTP servers).
The class TftpRequest
handles all low level details of the TFTP
protocol, but the application logic must be implemented at a higher level.
Although that requires some coding, it provides maximum flexibility. For that
same reason, some knowledge of the TFTP standard is recommended in
order to understand and explore all possibilites of the class, specially
regarding TFTP options.
TftpRequest
must be
restricted to the characters available in the US-ASCII character set (the
first 128 characters of the Unicode character set). That is a limitation of
the TFTP protocol and using characters outside that range leads do undefined
behaviour.
Whenever the TFTP standard defines strings as case insensitive (namely the
transfer mode and options keys) TftpRequest
always converts
them to lowercase. That means that the case of case insensitive strings does
not matter, whether the string is passed to the class by application logic or
received from a remote host. Likewise, any case insensitive string the
TftpRequest
class returns or sends to a remote host is always
lowercase only.
TftpRequest
provides full support for TFTP options.
Several methods are provided so that the application logic can set options,
get their values or query the options of a TFTP request.The class also understands the standard options in several ways, that is, it provides convenient constants for the standard options, provides a set of specific methods for them and, where applicable, the standard options affect the class behaviour if set (timeout and block size options). Other than that, all options are just exposed as received from the remote host and sent as set by the local host. That way it is possible to implement any custom options, if desired.
When a TftpRequest
instance is constructed with the default
constructor, it contains no options (that is intended to be used by TFTP
clients). The application must use the provided methods to set the options
desired. After connecting to the server (getInputStream()
and
getOutputStream()
) the TftpRequest
will contain
only the options returned by the server (the options set by the
application are lost). At this time, the query methods can be used to
process any options returned by the server.
When a TftpRequest
instance is constructed with the constructor
that accepts a datagram, it will contain all options specified in the
datagram (that is intended to be used by TFTP servers). The server must
then use the provided methods to change and remove options as desired.
When the request is answered (getInputStream()
and
getOutputStream()
) all options set in the TftpRequest
will be sent to the client as part of the answer.
Notice that a server (specially older ones) may not support the TFTP options extension and may understand TFTP options as an ill formed TFTP request, sending an error if options are used. In that case, the client will get an exception and it is up to the implementation to try the request again without any options.
TftpRequest
is straightforward.
A basic TFTP client follows the following outline:
TftpRequest
using the default constructorsetHost(java.net.InetAddress)
) and port number
(setPort(int)
) of the serversetOperation(int)
) and the file name
(setFileName(java.lang.String)
)getInputStream()
) for a read request,
or an output stream (getOutputStream()
) for a write oneTftpRequest
using the default constructorsetDefaultTimeout(int)
,
setRetries(int)
)setHost(java.net.InetAddress)
) and port number
(setPort(int)
) of the serversetOperation(int)
) and the file name
(setFileName(java.lang.String)
)setMode(java.lang.String)
), if necessarysetTimeout(int)
, setTransferSize(long)
,
setBlockSize(int)
), if desiredsetOption(String,String)
and
setOption(String,long)
), if desiredgetInputStream()
) for a read request,
or an output stream (getOutputStream()
) for a write oneoptionsNames()
,
getOptionAsString(java.lang.String)
, getOptionAsLong(java.lang.String)
, getOptionAsInt(java.lang.String)
,
isOptionSet(java.lang.String)
, isOptionValidAsLong(java.lang.String)
, isOptionValidAsInt(java.lang.String)
,
getTimeout()
, isTimeoutSet()
, getTransferSize()
,
isTransferSizeSet()
, getBlockSize()
, isBlockSizeSet()
),
aborting if necessary (sendError(int, java.lang.String)
)TftpRequest
object to be reused by repeating the
steps 2 to 11 above, but care must be taken to reset all properties, as needed, for the
next request.
getRequest(int)
,
getRequest()
)getOperation()
and getFileName()
)
and abort if the request can't be honored (sendError(int, java.lang.String)
)getInputStream()
) for a write
request, or an output stream (getOutputStream()
) for a
read one (notice that this is the inverse of the client)getRequest(int)
,
getRequest()
)getOperation()
, getFileName()
and getMode()
) and abort if the request can't be honored
(sendError(int, java.lang.String)
)optionsNames()
,
getOptionAsString(java.lang.String)
, getOptionAsLong(java.lang.String)
, getOptionAsInt(java.lang.String)
,
isOptionSet(java.lang.String)
, isOptionValidAsLong(java.lang.String)
, isOptionValidAsInt(java.lang.String)
,
getTimeout()
, isTimeoutSet()
, getTransferSize()
,
isTransferSizeSet()
, getBlockSize()
), isBlockSizeSet()
),
aborting if necessary (sendError(int, java.lang.String)
)setTimeout(int)
,
setTransferSize(long)
, setBlockSize(int)
, setOption(String,String)
,
setOption(String,long)
, clearOptions()
, clearOption(java.lang.String)
,
clearTimeout()
, clearTransferSize()
, clearBlockSize()
);
notice that any option not explicitly set or cleared will keep the value
sent by the clientgetInputStream()
) for a write
request, or an output stream (getOutputStream()
) for a
read one (notice that this is the inverse of the client)
Field Summary | |
---|---|
static java.lang.String |
BLOCK_SIZE
String for the block size standard option. |
static int |
DEFAULT_RETRIES
Default number of retries. |
static int |
DEFAULT_TIMEOUT
Default timeout (seconds). |
static java.lang.String |
MAIL
String for the mail transfer mode. |
static java.lang.String |
NETASCII
String for the netascii transfer mode. |
static java.lang.String |
OCTET
String for the octet transfer mode. |
static int |
READ
Code for the read operation. |
static int |
STANDARD_BLOCK_SIZE
TFTP standard block size. |
static int |
STANDARD_TFTP_PORT
TFTP protocol standard port. |
static java.lang.String |
TIMEOUT
String for the timeout standard option. |
static java.lang.String |
TRANSFER_SIZE
String for the transfer size standard option. |
static int |
WRITE
Code for the write operation. |
Constructor Summary | |
---|---|
TftpRequest()
Constructs a new TftpRequest . |
Method Summary | |
---|---|
static void |
abortGetRequest()
Aborts an in-progress call to the methods getRequest(int) or
getRequest() . |
void |
clearBlockSize()
Removes the block size standard option from this request. |
void |
clearOption(java.lang.String option)
Removes an option from this request. |
void |
clearOptions()
Removes all options from this request. |
void |
clearTimeout()
Removes the timeout standard option from this request. |
void |
clearTransferSize()
Removes the transfer size standard option from this request. |
int |
getBlockSize()
Returns the value of the block size standard option. |
int |
getDefaultTimeout()
Returns the default timeout. |
java.lang.String |
getFileName()
Returns the file name of this request. |
java.net.InetAddress |
getHost()
Returns the remote host address. |
java.io.InputStream |
getInputStream()
Returns an InputStream object that receives data from the
remote host. |
java.lang.String |
getMode()
Returns the transfer mode of this request. |
int |
getOperation()
Returns the operation this request performs. |
int |
getOptionAsInt(java.lang.String option)
Returns the value of an option as an int value. |
long |
getOptionAsLong(java.lang.String option)
Returns the value of an option as a long value. |
java.lang.String |
getOptionAsString(java.lang.String option)
Returns the value of a string option. |
java.io.OutputStream |
getOutputStream()
Returns an OutputStream object that receives data from the
remote host. |
int |
getPort()
Returns the remote host port. |
static TftpRequest |
getRequest()
Waits for an incoming client TFTP request on the standard TFTP port. |
static TftpRequest |
getRequest(int port)
Waits for an incoming client TFTP request on a given port. |
int |
getRequestBlockSize()
Returns the block size being used by this request. |
int |
getRequestTimeout()
Returns the timeout being used by this request. |
int |
getRetries()
Returns the number of retries of this request. |
int |
getTimeout()
Returns the value of the timeout standard option. |
long |
getTransferSize()
Returns the value of the transfer size standard option. |
boolean |
isBlockSizeSet()
Tests whether the block size standard option has been set. |
boolean |
isOptionSet(java.lang.String option)
Tests whether an option is set or not. |
boolean |
isOptionValidAsInt(java.lang.String option)
Tests whether an option has a valid int value. |
boolean |
isOptionValidAsLong(java.lang.String option)
Tests whether an option has a valid long value. |
boolean |
isTimeoutSet()
Tests whether the timeout standard option has been set. |
boolean |
isTransferSizeSet()
Tests whether the transfer size standard option has been set. |
java.util.Iterator |
optionsNames()
Returns an iterator over all options of this request. |
void |
sendError(int errorCode,
java.lang.String errorMsg)
Signals an error the the remote host. |
void |
setBlockSize(int blockSize)
Sets the block size standard option. |
void |
setDefaultTimeout(int timeout)
Sets the default timeout. |
void |
setFileName(java.lang.String fileName)
Sets the file name for this request. |
void |
setHost(java.net.InetAddress host)
Sets the address of the remote host. |
void |
setMode(java.lang.String mode)
Sets the transfer mode for this request. |
void |
setOperation(int operation)
Sets the operation this request should perform. |
void |
setOption(java.lang.String option,
long value)
Sets a numeric option for this request. |
void |
setOption(java.lang.String option,
java.lang.String value)
Sets a string option for this request. |
void |
setPort(int port)
Sets the port of the remote host. |
void |
setRetries(int retries)
Sets the number of retries for this request. |
void |
setTimeout(int timeout)
Sets the timeout standard option. |
void |
setTransferSize(long transferSize)
Sets the transfer size standard option. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final int DEFAULT_TIMEOUT
public static final int DEFAULT_RETRIES
public static final int STANDARD_BLOCK_SIZE
public static final int STANDARD_TFTP_PORT
public static final int READ
public static final int WRITE
public static final java.lang.String TIMEOUT
public static final java.lang.String TRANSFER_SIZE
public static final java.lang.String BLOCK_SIZE
public static final java.lang.String NETASCII
public static final java.lang.String OCTET
public static final java.lang.String MAIL
Constructor Detail |
---|
public TftpRequest()
TftpRequest
. Sets the default timeout to
DEFAULT_TIMEOUT
, the number of retries to DEFAULT_RETRIES
,
the port to STANDARD_TFTP_PORT
and the transfer mode to OCTET
.
The constructor does not set any option.
Method Detail |
---|
public static TftpRequest getRequest(int port) throws java.io.IOException
TftpRequest
object. The remote host address and
port are set with the IP address and port of the sender, and the operation,
file name, transfer mode and options with the values present in the TFTP
request. The default timeout and number of retries are always set to
DEFAULT_TIMEOUT
and DEFAULT_RETRIES
, respectively.The request is assumed to have been sent by a TFTP client, however it is the application responsibility to make any validation (operation, file name, transfer mode, options and so on) necessary before proceeding.
Notice that the method listens for requests on all IP addresses of the
local machine and blocks forever until a request is received. The method
abortGetRequest()
must be used to abort getRequest
(in that case the application gets an exception).
port
- port to listen (STANDARD_TFTP_PORT
for the
standard TFTP service port)
java.io.IOException
- if an error occurs while waiting for a request
java.io.InterruptedIOException
- if the method has been aborted by abortGetRequest()
getRequest()
,
abortGetRequest()
public static TftpRequest getRequest() throws java.io.IOException
getRequest(int)
passing
STANDARD_TFTP_PORT
as parameter.
java.io.IOException
- if an error occurs while waiting for a request
java.io.InterruptedIOException
- if the method has been aborted by abortGetRequest()
getRequest(int)
,
abortGetRequest()
public static void abortGetRequest() throws java.io.IOException
getRequest(int)
or
getRequest()
. If there is no call to the mentioned methods,
abortGetRequest
waits until one of them is called, so that
when the method returns the call is guaranteed to be aborted and the
thread, received an exception.
Notice that abortGetRequest
must be called from another
thread to produce the desired result, that is, interrupt the one that is
blocked on getRequest(int)
or getRequest(int)
.
java.io.IOException
- if a communication error occursgetRequest(int)
,
getRequest()
public void setRetries(int retries)
TftpRequest
tries to send a packet again to the
remote host if it does not answer. Notice that this is in addition to the
first time, that is, if the number of retries is set to 3,
TftpRequest
will send a packet to the remote host 4 times
before giving up, if it does not answer.
retries
- number of retries
java.lang.IllegalArgumentException
- if the number of retries is less than zeropublic int getRetries()
public void setHost(java.net.InetAddress host)
host
- the remote host address
java.lang.IllegalArgumentException
- if the host is null
public java.net.InetAddress getHost()
public void setPort(int port)
port
- the remote host port (STANDARD_TFTP_PORT
for the
standard port used by TFTP servers)
java.lang.IllegalArgumentException
- if port is outside the range from 1 to 65535public int getPort()
public void setOperation(int operation)
READ
) and
writing a file to a server (WRITE
).
operation
- operation to performpublic int getOperation()
public void setFileName(java.lang.String fileName)
fileName
- the file name
java.lang.IllegalArgumentException
- if the file name is null
public java.lang.String getFileName()
TftpRequest
class
does not interpret file names in any way, processing the file name is
entirely up to the application logic.
public void setMode(java.lang.String mode)
TftpRequest
provides convenient constants for the transfer modes defined by the TFTP
protocol standard:
Notice that, whatever the transfer mode is, the class TftpRequest
does not perform any conversion on the data, that must be done by the
application logic, if necessary.
mode
- transfer mode
java.lang.IllegalArgumentException
- if the transfer mode is null
public java.lang.String getMode()
public java.util.Iterator optionsNames()
next
method returns the option name, as a String
object. The iterator's remove
method can be used to remove
the last option returned, according the java.util.Iterator
interface contract.
public void setOption(java.lang.String option, java.lang.String value)
TIMEOUT
, TRANSFER_SIZE
and
BLOCK_SIZE
can be used to set the standard options.
option
- option to setvalue
- value to set, passed as a String
java.lang.IllegalArgumentException
- if the option or the value is
null
public void setOption(java.lang.String option, long value)
setOption(String,String)
, but taking a long
as the
option value.
option
- option to setvalue
- value to set, passed as a long
public boolean isOptionSet(java.lang.String option)
TIMEOUT
, TRANSFER_SIZE
and BLOCK_SIZE
can be
used to test the standard options.
option
- option to test
true
if the option is set, false
otherwisepublic java.lang.String getOptionAsString(java.lang.String option)
null
. The constants
TIMEOUT
, TRANSFER_SIZE
and BLOCK_SIZE
can be used to get the standard options.
option
- option to return
String
, or
null
if not setpublic boolean isOptionValidAsLong(java.lang.String option)
long
value. The method
isOptionValidAsLong
tests whether the value of a given option
(which is always a string) is a valid long
value, that is,
can be successfuly converted to a long
.
The constant TRANSFER_SIZE
can be used to test the transfer size
standard option. Notice that the method throws an exception if the option does
not exist. The method isOptionSet(java.lang.String)
can be used to test this case.
option
- option to test
true
if the option value can be converted to a
long
, false
otherwisepublic long getOptionAsLong(java.lang.String option)
long
value. This method
is the same as getOptionAsString(java.lang.String)
, but returning the option value
as a long
. The constant TRANSFER_SIZE
can be used to
get the transfer size standard option.
Notice that the method throws an exception if the option does not exist
or if its value is not a valid long
. The methods
isOptionSet(java.lang.String)
and isOptionValidAsLong(java.lang.String)
can be used to
test for these cases.
option
- option to return
long
public boolean isOptionValidAsInt(java.lang.String option)
int
value. The method
isOptionValidAsInt
tests whether the value of a given option
(which is always a string) is a valid int
value, that is,
can be successfuly converted to an int
.
The constants TIMEOUT
and BLOCK_SIZE
can be used to test
the timeout and block size standard options. Notice that the
method throws an exception if the option does not exist. The method
isOptionSet(java.lang.String)
can be used to test this case.
option
- option to test
true
if the option value can be converted to an
int
, false
otherwisepublic int getOptionAsInt(java.lang.String option)
int
value. This method
is the same as getOptionAsString(java.lang.String)
, but returning the option value
as an int
. The constants TIMEOUT
and BLOCK_SIZE
can be used to get the timeout and block size standard options.
Notice that the method throws an exception if the option does not exist
or if its value is not a valid int
. The methods
isOptionSet(java.lang.String)
and isOptionValidAsInt(java.lang.String)
can be used to
test for these cases.
option
- option to return
int
public void clearOption(java.lang.String option)
TIMEOUT
,
TRANSFER_SIZE
and BLOCK_SIZE
can be used to remove
the standard options.
option
- option to removepublic void clearOptions()
public void setTimeout(int timeout)
setTimeout
is the same as calling the method setOption(String,long)
with the
constant TIMEOUT
.
If the timeout standard option is set, the TftpRequest
class uses the value specified as the timeout to talk to the remote
host.
timeout
- timeout to set, in secondssetDefaultTimeout(int)
,
getRequestTimeout()
public boolean isTimeoutSet()
isOptionSet(java.lang.String)
with the constant
TIMEOUT
.
true
if the timeout standard option is set
in this request, false
otherwisepublic int getTimeout()
getOptionAsInt(java.lang.String)
with the TIMEOUT
constant.
public void clearTimeout()
clearOption(java.lang.String)
with the constant
TIMEOUT
.
public void setDefaultTimeout(int timeout)
timeout
- default timeout, in seconds
java.lang.IllegalArgumentException
- if the timeout is less than or equal to
zerosetTimeout(int)
,
getRequestTimeout()
public int getDefaultTimeout()
public int getRequestTimeout()
TftpRequest
. It is
the value of the timeout standard option if it has been set and its value
is valid (numeric and greater than zero) or the default timeout otherwise.
setTimeout(int)
,
setDefaultTimeout(int)
public void setTransferSize(long transferSize)
setTransferSize
is the same as calling the method
setOption(String,long)
with the constant
TRANSFER_SIZE
.
transferSize
- value of the transfer size optionpublic boolean isTransferSizeSet()
isOptionSet(java.lang.String)
with the constant
TRANSFER_SIZE
.
true
if the transfer size standard option is set
in this request, false
otherwisepublic long getTransferSize()
getOptionAsLong(java.lang.String)
with the TRANSFER_SIZE
constant.
public void clearTransferSize()
clearOption(java.lang.String)
with the constant
TRANSFER_SIZE
.
public void setBlockSize(int blockSize)
setBlockSize
is the same as calling the method
setOption(String,long)
with the constant BLOCK_SIZE
.
If the block size standard option is set, the TftpRequest
class uses the value specified as the block size for the request. If the
block size option is not set, the standard block size, as determined
by the TFTP specification, will be used.
blockSize
- block size to setgetRequestBlockSize()
public boolean isBlockSizeSet()
isOptionSet(java.lang.String)
with the constant
BLOCK_SIZE
.
true
if the block size standard option is set
in this request, false
otherwisepublic int getBlockSize()
getOptionAsInt(java.lang.String)
with the BLOCK_SIZE
constant.
public void clearBlockSize()
clearOption(java.lang.String)
with the constant
BLOCK_SIZE
.
public int getRequestBlockSize()
TftpRequest
. It is
the value of the block size standard option, if it has been set and
if its value is valid (numeric and greater than zero) or
STANDARD_BLOCK_SIZE
otherwise.
setBlockSize(int)
public java.io.InputStream getInputStream() throws java.io.IOException
InputStream
object that receives data from the
remote host. The getInputStream
operation depends on whether
this TftpRequest
operation property is READ
or WRITE
.
If it is READ
, the method sends the request to the remote host
(which is expected to be a TFTP server) according all properties and
options, waits for its acknowledgement and returns an InputStream
object that must be used to receive the file from the server. Also, after
getInputStream
returns, this TftpRequest
will
contain the options (if any) returned by the server.
If the operation is WRITE
then it is supposed to be a request
received from a TFTP client (returned by the methods getRequest(int)
or getRequest()
). In this case, getInputStream
acknowledges the request to the client (sending any options set in this
TftpRequest
to it) and returns an InputStream
object that must be used to receive the file from the client.
Any error that occurs either while establishing the connection or while
reading the InputStream
throws an IOException
.
The exact class depends on the nature of the error and version of the JVM,
however if the error was signaled by the remote host then the exception
will be an instance of the TftpErrorException
class.
At any time the application can abort the request by calling the method
sendError(int, java.lang.String)
, which signals an error to the remote host. If
multithreading is being used, calling the close()
method of
the returned InputStream
object makes any thread blocked
on it to get an exception.
Notice that the close()
method of the
InputStream
object returned must be called after all data have
been written, otherwise the last data block will not be acknowledged,
causing the remote host to timeout.
InputStream
to receive data from the remote host;
notice that encapsulating the stream on a
BufferedInputStream
does not improve the performance
java.io.IOException
- if a communication error or timeout occurs or if
the remote host signals an error
java.lang.IllegalStateException
- if the host or file name were not specified
(they are null
) or if the
operation is not validpublic java.io.OutputStream getOutputStream() throws java.io.IOException
OutputStream
object that receives data from the
remote host. The getOutputStream
operation depends on whether
this TftpRequest
operation property is WRITE
or READ
.
If it is WRITE
, the method sends the request to the remote host
(which is expected to be a TFTP server) according all properties and
options, waits for its acknowledgement and returns an
OutputStream
object that must be used to send
the file to the server. Also, after getOutputStream
returns,
this TftpRequest
will contain the options (if any) returned
by the server.
If the operation is READ
then it is supposed to be a request
received from a TFTP client (returned by the methods getRequest(int)
or getRequest()
). In this case, getOutputStream
acknowledge the request to the client (sending any options set in this
TftpRequest
to it) and returns an OutputStream
object that must be used to send the file to the client.
Any error that occurs either while establishing the connection or while
writing to the OutputStream
throws an IOException
.
The exact class depends on the nature of the error and version of the JVM,
however if the error was signaled by the remote host then the exception
will be an instance of the TftpErrorException
class.
At any time the application can abort the request by calling the method
sendError(int, java.lang.String)
, which signals an error to the remote host. If
multithreading is being used, calling the close()
method of
the returned OutputStream
object makes any thread blocked
on it to get an exception.
Notice that the close()
method of the
OutputStream
object returned must be called after all data have
been written, otherwise the last data block will not be sent to the remote
host and the request will fail.
OutputStream
to send data to the remote host;
notice that encapsulating the stream on a
BufferedOutputStream
does not improve the performance
java.io.IOException
- if a communication error or timeout occurs or if
the remote host signals an error
java.lang.IllegalStateException
- if the host or file name were not specified
(they are null
) or if the
operation is not validpublic void sendError(int errorCode, java.lang.String errorMsg) throws java.io.IOException
sendError
sends a TFTP error packet to the remote host, thus effectively terminating
this TFTP request. It must be used to signal any error condition found
by the application logic or just to abort the request.
To signal an error the application must provide a numeric error code and
a non-null (although it can be empty) error message. The class
TftpErrorException
defines convenient constants for the standard
TFTP error codes.
The method sendError
can be called after receiveing a request
from a TFTP client (after getting a request with getRequest(int)
or
getRequest()
) or after establishing a connection with
a TFTP server (after calling one of the getInputStream()
or
getOutputStream()
methods). After calling sendError
no
further I/O must be made on the InputStream
and
OutputStream
objects returned by the methods
getInputStream()
and getOutputStream()
, respectively.
errorCode
- numeric error code (see TftpErrorException
)errorMsg
- human readable error message
java.io.IOException
- if a communication error occurs
java.lang.IllegalArgumentException
- if the error code is outside the range
from 0 to 65535 or if the error message
is null
java.lang.IllegalStateException
- if the host were not specified
|
Copyright © 2004 LCM Software All rights reserved |
|||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |