Tuesday, November 25, 2008

TFTP server for Java

TFTP server :

I have searched in goole about TFTP server. I have collected and created a simple TFTP server implementation to solve my problem.

TFTP server uses UDP protocol and consumes 69 port. This TFTP server extends from TFTPClient.. No bother just here I used get get and put methods. We can directly use TFTP.

We need to download
"org.apache.commons.net.tftp" package to implement TFTP Server
Just try this code. Which will send file to remote system.



import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;


import org.apache.commons.net.tftp.TFTPClient;
import org.apache.commons.net.tftp.TFTPDataPacket;
import org.apache.commons.net.tftp.TFTPPacket;
import org.apache.commons.net.tftp.TFTPRequestPacket;

public class TFTPServer extends TFTPClient implements Runnable
{
public void run ()
{
try
{

open(69, java.net.InetAddress.getByName(null));
while (true)
{
checkForRequests();
}

}
catch (Exception e)
{

e.printStackTrace();
}

beginBufferedOps();
}

public TFTPServer()
{

}

public static byte[] getBytesFromFile (File file) throws IOException
{
InputStream is = new FileInputStream(file);

// Get the size of the file
long length = file.length();

// You cannot create an array using a long type.
// It needs to be an int type.
// Before converting to an int type, check
// to ensure that file is not larger than Integer.MAX_VALUE.
if (length > Integer.MAX_VALUE)
{
// File is too large
}

// Create the byte array to hold the data
byte[] bytes = new byte[(int) length];

// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < numread =" is.read(bytes,">= 0)
{
offset += numRead;
}

// Ensure all the bytes have been read in
if (offset < bytes.length)
{
throw new IOException("Could not completely read file " + file.getName());
}

// Close the input stream and return bytes
is.close();
return bytes;
}

/**
* Sends a bogus file to the TFTP client, and prints a message on the screen.
*
* @param addr
* Address to send to
* @param port
* Port to send to
*/
private void sendFile (File file, InetAddress addr, int port)
{
try
{

int bytesSent = 0;
int blockNum = 1;
byte[] inputBuf = getBytesFromFile(file);
while (bytesSent < inputBuf.length)
{
/*
* Note: this loop assumes that the buffer does not end on an
* exact 512 byte boundary! If it did, you would need to send an
* extra zero-length data packet at the end. As it is, the
* less-than-512 packet signifies that it is the end.
*/

// send a data packet with the next bytes from our "file"
int toSend = 512;
if (bytesSent + 512 > inputBuf.length)
{
toSend = inputBuf.length - bytesSent;
}

TFTPDataPacket dPack = new TFTPDataPacket(addr, port, blockNum, inputBuf, bytesSent, toSend);
send(dPack);

blockNum++;
bytesSent += toSend;

// get acknowledgement packet
TFTPPacket pack = receive();

/*
* Verify it is a acknowledge packet -- Note: should check some
* other things, like it being the correct block number.
*/
if (pack.getType() != TFTPPacket.ACKNOWLEDGEMENT)
{
// printPacketError( pack, "read file request" );
return;
}
} // end of while loop sending file

System.out.println("File sent successfully");
}
catch (Exception e)
{
System.out.println("Exception in sending file: " + e.getMessage());
}
}

public void checkForRequests ()
{
TFTPPacket pack = null;
try
{
pack = receive();
}
catch (Exception e)
{
/*
* Normally this should mean a timeout occurred -- do nothing, and
* return. In a real application, should check the exception type!
*/
return;
}

// check packet type and send/receive file
try
{
switch (pack.getType())
{
case TFTPPacket.READ_REQUEST:
TFTPRequestPacket rPack = (TFTPRequestPacket) pack;
System.out.println("Read request received for file " + rPack.getFilename() + " from address " + rPack.getPort());
File file = new File("c:\\" + rPack.getFilename());
InputStream is = new BufferedInputStream(new FileInputStream(file));
this.sendFile(file, pack.getAddress(), pack.getPort());
break;

case TFTPPacket.WRITE_REQUEST:
TFTPRequestPacket wPack = (TFTPRequestPacket) pack;
System.out.println("Write request received for file " + wPack.getFilename() + " from address " + wPack.getPort());
// receiveFile( pack.getAddress(), pack.getPort() );
break;

default:
// printPacketError( pack, "checking for requests" );
}
}
catch (Exception e)
{
e.printStackTrace();
}
}

/**
* @param args
*/
public static void main (String[] args)
{
TFTPServer test = new TFTPServer();
try
{

test.open(69, java.net.InetAddress.getByName(null));
while (true)
{
test.checkForRequests();
}
//test.receive();
// TFTPdata data;

}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}

test.beginBufferedOps();
}

}