1 package org.apache.commons.net.tftp;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Commons" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import java.io.IOException;
58 import java.io.InterruptedIOException;
59 import java.net.DatagramPacket;
60 import java.net.SocketException;
61 import org.apache.commons.net.DatagramSocketClient;
62
63 /****
64 * The TFTP class exposes a set of methods to allow you to deal with the TFTP
65 * protocol directly, in case you want to write your own TFTP client or
66 * server. However, almost every user should only be concerend with
67 * the <a href="org.apache.commons.net.DatagramSocketClient.html#open"> open() </a>,
68 * and <a href="org.apache.commons.net.DatagramSocketClient.html#close"> close() </a>,
69 * methods. Additionally,the a
70 * <a href="org.apache.commons.net.DatagramSocketClient.html#setDefaultTimeout">
71 * setDefaultTimeout() </a> method may be of importance for performance tuning.
72 * <p>
73 * Details regarding the TFTP protocol and the format of TFTP packets can
74 * be found in RFC 783. But the point of these classes is to keep you
75 * from having to worry about the internals.
76 * <p>
77 * <p>
78 * @author Daniel F. Savarese
79 * @see org.apache.commons.net.DatagramSocketClient
80 * @see TFTPPacket
81 * @see TFTPPacketException
82 * @see TFTPClient
83 ***/
84
85 public class TFTP extends DatagramSocketClient
86 {
87 /****
88 * The ascii transfer mode. Its value is 0 and equivalent to NETASCII_MODE
89 ***/
90 public static final int ASCII_MODE = 0;
91
92 /****
93 * The netascii transfer mode. Its value is 0.
94 ***/
95 public static final int NETASCII_MODE = 0;
96
97 /****
98 * The binary transfer mode. Its value is 1 and equivalent to OCTET_MODE.
99 ***/
100 public static final int BINARY_MODE = 1;
101
102 /****
103 * The image transfer mode. Its value is 1 and equivalent to OCTET_MODE.
104 ***/
105 public static final int IMAGE_MODE = 1;
106
107 /****
108 * The octet transfer mode. Its value is 1.
109 ***/
110 public static final int OCTET_MODE = 1;
111
112 /****
113 * The default number of milliseconds to wait to receive a datagram
114 * before timing out. The default is 5000 milliseconds (5 seconds).
115 ***/
116 public static final int DEFAULT_TIMEOUT = 5000;
117
118 /****
119 * The default TFTP port according to RFC 783 is 69.
120 ***/
121 public static final int DEFAULT_PORT = 69;
122
123 /****
124 * The size to use for TFTP packet buffers. Its 4 plus the
125 * TFTPPacket.SEGMENT_SIZE, i.e. 516.
126 ***/
127 static final int PACKET_SIZE = TFTPPacket.SEGMENT_SIZE + 4;
128
129 /**** A buffer used to accelerate receives in bufferedReceive() ***/
130 private byte[] __receiveBuffer;
131
132 /**** A datagram used to minimize memory allocation in bufferedReceive() ***/
133 private DatagramPacket __receiveDatagram;
134
135 /**** A datagram used to minimize memory allocation in bufferedSend() ***/
136 private DatagramPacket __sendDatagram;
137
138 /****
139 * A buffer used to accelerate sends in bufferedSend().
140 * It is left package visible so that TFTPClient may be slightly more
141 * efficient during file sends. It saves the creation of an
142 * additional buffer and prevents a buffer copy in _newDataPcket().
143 ***/
144 byte[] _sendBuffer;
145
146
147 /****
148 * Returns the TFTP string representation of a TFTP transfer mode.
149 * Will throw an ArrayIndexOutOfBoundsException if an invalid transfer
150 * mode is specified.
151 * <p>
152 * @param mode The TFTP transfer mode. One of the MODE constants.
153 * @return The TFTP string representation of the TFTP transfer mode.
154 ***/
155 public static final String getModeName(int mode)
156 {
157 return TFTPRequestPacket._modeStrings[mode];
158 }
159
160 /****
161 * Creates a TFTP instance with a default timeout of DEFAULT_TIMEOUT,
162 * a null socket, and buffered operations disabled.
163 ***/
164 public TFTP()
165 {
166 setDefaultTimeout(DEFAULT_TIMEOUT);
167 __receiveBuffer = null;
168 __receiveDatagram = null;
169 }
170
171 /****
172 * This method synchronizes a connection by discarding all packets that
173 * may be in the local socket buffer. This method need only be called
174 * when you implement your own TFTP client or server.
175 * <p>
176 * @exception IOException if an I/O error occurs.
177 ***/
178 public final void discardPackets() throws IOException
179 {
180 int to;
181 DatagramPacket datagram;
182
183 datagram = new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);
184
185 to = getSoTimeout();
186 setSoTimeout(1);
187
188 try
189 {
190 while (true)
191 _socket_.receive(datagram);
192 }
193 catch (SocketException e)
194 {
195 // Do nothing. We timed out so we hope we're caught up.
196 }
197 catch (InterruptedIOException e)
198 {
199 // Do nothing. We timed out so we hope we're caught up.
200 }
201
202 setSoTimeout(to);
203 }
204
205
206 /****
207 * This is a special method to perform a more efficient packet receive.
208 * It should only be used after calling
209 * <a href="#beginBufferedOps"> beginBufferedOps() </a>. beginBufferedOps()
210 * initializes a set of buffers used internally that prevent the new
211 * allocation of a DatagramPacket and byte array for each send and receive.
212 * To use these buffers you must call the bufferedReceive() and
213 * bufferedSend() methods instead of send() and receive(). You must
214 * also be certain that you don't manipulate the resulting packet in
215 * such a way that it interferes with future buffered operations.
216 * For example, a TFTPDataPacket received with bufferedReceive() will
217 * have a reference to the internal byte buffer. You must finish using
218 * this data before calling bufferedReceive() again, or else the data
219 * will be overwritten by the the call.
220 * <p>
221 * @return The TFTPPacket received.
222 * @exception InterruptedIOException If a socket timeout occurs. The
223 * Java documentation claims an InterruptedIOException is thrown
224 * on a DatagramSocket timeout, but in practice we find a
225 * SocketException is thrown. You should catch both to be safe.
226 * @exception SocketException If a socket timeout occurs. The
227 * Java documentation claims an InterruptedIOException is thrown
228 * on a DatagramSocket timeout, but in practice we find a
229 * SocketException is thrown. You should catch both to be safe.
230 * @exception IOException If some other I/O error occurs.
231 * @exception TFTPPacketException If an invalid TFTP packet is received.
232 ***/
233 public final TFTPPacket bufferedReceive() throws IOException,
234 InterruptedIOException, SocketException, TFTPPacketException
235 {
236 __receiveDatagram.setData(__receiveBuffer);
237 __receiveDatagram.setLength(__receiveBuffer.length);
238 _socket_.receive(__receiveDatagram);
239
240 return TFTPPacket.newTFTPPacket(__receiveDatagram);
241 }
242
243 /****
244 * This is a special method to perform a more efficient packet send.
245 * It should only be used after calling
246 * <a href="#beginBufferedOps"> beginBufferedOps() </a>. beginBufferedOps()
247 * initializes a set of buffers used internally that prevent the new
248 * allocation of a DatagramPacket and byte array for each send and receive.
249 * To use these buffers you must call the bufferedReceive() and
250 * bufferedSend() methods instead of send() and receive(). You must
251 * also be certain that you don't manipulate the resulting packet in
252 * such a way that it interferes with future buffered operations.
253 * For example, a TFTPDataPacket received with bufferedReceive() will
254 * have a reference to the internal byte buffer. You must finish using
255 * this data before calling bufferedReceive() again, or else the data
256 * will be overwritten by the the call.
257 * <p>
258 * @param TFTPPacket The TFTP packet to send.
259 * @exception IOException If some I/O error occurs.
260 ***/
261 public final void bufferedSend(TFTPPacket packet) throws IOException
262 {
263 _socket_.send(packet._newDatagram(__sendDatagram, _sendBuffer));
264 }
265
266
267 /****
268 * Initializes the internal buffers. Buffers are used by
269 * <a href="#bufferedSend"> bufferedSend() </a> and
270 * <a href="#bufferedReceive"> bufferedReceive() </a>. This
271 * method must be called before calling either one of those two
272 * methods. When you finish using buffered operations, you must
273 * call <a href="#endBufferedOps"> endBufferedOps() </a>.
274 ***/
275 public final void beginBufferedOps()
276 {
277 __receiveBuffer = new byte[PACKET_SIZE];
278 __receiveDatagram =
279 new DatagramPacket(__receiveBuffer, __receiveBuffer.length);
280 _sendBuffer = new byte[PACKET_SIZE];
281 __sendDatagram =
282 new DatagramPacket(_sendBuffer, _sendBuffer.length);
283 }
284
285 /****
286 * Releases the resources used to perform buffered sends and receives.
287 ***/
288 public final void endBufferedOps()
289 {
290 __receiveBuffer = null;
291 __receiveDatagram = null;
292 _sendBuffer = null;
293 __sendDatagram = null;
294 }
295
296
297 /****
298 * Sends a TFTP packet to its destination.
299 * <p>
300 * @param TFTPPacket The TFTP packet to send.
301 * @exception IOException If some I/O error occurs.
302 ***/
303 public final void send(TFTPPacket packet) throws IOException
304 {
305 _socket_.send(packet.newDatagram());
306 }
307
308
309 /****
310 * Receives a TFTPPacket.
311 * <p>
312 * @return The TFTPPacket received.
313 * @exception InterruptedIOException If a socket timeout occurs. The
314 * Java documentation claims an InterruptedIOException is thrown
315 * on a DatagramSocket timeout, but in practice we find a
316 * SocketException is thrown. You should catch both to be safe.
317 * @exception SocketException If a socket timeout occurs. The
318 * Java documentation claims an InterruptedIOException is thrown
319 * on a DatagramSocket timeout, but in practice we find a
320 * SocketException is thrown. You should catch both to be safe.
321 * @exception IOException If some other I/O error occurs.
322 * @exception TFTPPacketException If an invalid TFTP packet is received.
323 ***/
324 public final TFTPPacket receive() throws IOException, InterruptedIOException,
325 SocketException, TFTPPacketException
326 {
327 DatagramPacket packet;
328
329 packet = new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);
330
331 _socket_.receive(packet);
332
333 return TFTPPacket.newTFTPPacket(packet);
334 }
335
336
337 }
This page was automatically generated by Maven