FileDocCategorySizeDatePackage
RemCat.javaAPI DocExample4631Sun Feb 15 20:44:44 GMT 2004None

RemCat

public class RemCat extends Object

RemCat - remotely cat (DOS type) a file, using the TFTP protocol. Inspired by the "rcat" exercise in Learning Tree Course 363, UNIX Network Programming, by Dr. Chris Brown.

<[> Note that the TFTP server is NOT "internationalized"; the name and mode *in the protocol* are defined in terms of ASCII, not UniCode.

author
Chris R. Brown, original C version
author
Java version by Ian Darwin, http://www.darwinsys.com/.

Fields Summary
public static final int
TFTP_PORT
The UDP port number
protected final String
MODE
The mode we will use - octet for everything.
protected final int
OFFSET_REQUEST
The offset for the code/response as a byte
protected final int
OFFSET_PACKETNUM
The offset for the packet number as a byte
protected static boolean
debug
Debugging flag
public final int
OP_RRQ
TFTP op-code for a read request
public final int
OP_WRQ
TFTP op-code for a read request
public final int
OP_DATA
TFTP op-code for a read request
public final int
OP_ACK
TFTP op-code for a read request
public final int
OP_ERROR
TFTP op-code for a read request
protected static final int
PACKET_SIZE
protected String
host
protected InetAddress
servAddr
protected DatagramSocket
sock
protected byte[]
buffer
protected DatagramPacket
inp
protected DatagramPacket
outp
Constructors Summary
RemCat(String host)

		super();
		this.host = host;
		servAddr = InetAddress.getByName(host);
		sock = new DatagramSocket();
		buffer = new byte[PACKET_SIZE];
		outp = new DatagramPacket(buffer, PACKET_SIZE, servAddr, TFTP_PORT);
		inp = new DatagramPacket(buffer, PACKET_SIZE);
	
Methods Summary
public static voidmain(java.lang.String[] argv)
The main program that drives this network client.

param
argv[0] hostname, running TFTP server
param
argv[1..n] filename(s), must be at least one


	                      	 
	       
		if (argv.length < 2) {
			System.err.println("usage: rcat host filename[...]");
			System.exit(1);
		}
		if (debug)
			System.err.println("Java RemCat starting");
		RemCat rc = new RemCat(argv[0]);
		for (int i = 1; i<argv.length; i++) {
			if (debug)
				System.err.println("-- Starting file " + 
					argv[0] + ":" + argv[i] + "---");
			rc.readFile(argv[i]);
		}
	
voidreadFile(java.lang.String path)

		buffer[0] = 0;
		buffer[OFFSET_REQUEST] = OP_RRQ;		// read request
		int p = 2;			// number of chars into buffer

		// Convert filename String to bytes in buffer , using "p" as an
		// offset indicator to get all the bits of this request
		// in exactly the right spot.
		byte[] bTemp = path.getBytes();	// i.e., ASCII
		System.arraycopy(bTemp, 0, buffer, p, path.length());
		p += path.length();
		buffer[p++] = 0;		// null byte terminates string

		// Similarly, convert MODE ("stream" or "octet") to bytes in buffer
		bTemp = MODE.getBytes();	// i.e., ASCII
		System.arraycopy(bTemp, 0, buffer, p, MODE.length());
		p += MODE.length();
		buffer[p++] = 0;		// null terminate

		/* Send Read Request to tftp server */
		outp.setLength(p);
		sock.send(outp);

		/* Loop reading data packets from the server until a short
		 * packet arrives; this indicates the end of the file.
		 */
		int len = 0;
		do {
			sock.receive(inp);
			if (debug)
				System.err.println(
					"Packet # " + Byte.toString(buffer[OFFSET_PACKETNUM])+
					"RESPONSE CODE " + Byte.toString(buffer[OFFSET_REQUEST]));
			if (buffer[OFFSET_REQUEST] == OP_ERROR) {
				System.err.println("rcat ERROR: " +
					new String(buffer, 4, inp.getLength()-4));
				return;
			}
			if (debug)
				System.err.println("Got packet of size " +
					inp.getLength());

			/* Print the data from the packet */
			System.out.write(buffer, 4, inp.getLength()-4);

			/* Ack the packet. The block number we 
			 * want to ack is already in buffer so 
			 * we just change the opcode. The ACK is 
			 * sent to the port number which the server 
			 * just sent the data from, NOT to port 
			 * TFTP_PORT.
			 */
			buffer[OFFSET_REQUEST] = OP_ACK;
			outp.setLength(4);
			outp.setPort(inp.getPort());
			sock.send(outp);
		} while (inp.getLength() == PACKET_SIZE);

		if (debug)
			System.err.println("** ALL DONE** Leaving loop, last size " +
				inp.getLength());