HI guys, I'm trying to develop a tftp application in java.This is the specification i want: Task is to implement a modified version of TFTP, as follows: 1- version will still run on top of UDP, 2-However, instead of having each packet be acknowledged before sending the next one, you will implement a TCP type of functionality: packets can be sent without waiting for an acknowledgement. The receiver has to keep track of sequence numbers and implement some type of ordering to �restore� the original format of the file. The sender should be informed of missing packets through duplicate ACKs, as we saw in class. 3-You only have to implement the binary type of data transmission. 4-Your TFTP server should be multi-threaded, i.e., it should support multiple client requests. This is done by creating a new thread for each client request that is received. 5-Your application should survive short outages. Transferring a large file and disconnecting your Internet connection for a short time can test this. Upon reconnection, your client and the server should be able to pick up where they left off. I have created four files: 1)tftpClient:The client 2)tftpServer:the server 3)tftpTransfer:It performs packet transfer and stuff 4)UdpData erforms udp packet functionality
tftpClient: import java.net.*; import java.io.*; import java.util.*; public class tftpClient { public static void main(String argv[]) { String host= argv[0],fileName=argv[1],line; int replyLen,blockNum; try { // Process command line args..... InetAddress server = InetAddress.getByName(host); // DatagramSocket sock = new DatagramSocket(2000,InetAddress.getLocalHost()); DatagramSocket sock = new DatagramSocket(); FileOutputStream outFile = new FileOutputStream(fileName); // Create the request packet and send it off UdpData reqData = new UdpData(4+fileName.length()+5); // 5==len("octet") reqData.putInt(2,0); // RREQ opcode reqData.putString(fileName,2); // Requested file reqData.putString("octet",2+fileName.length()+1); // Trans mode DatagramPacket pack = reqData.mkPacket(server,2000); // 69==TFTP port sock.send(pack); System.out.println("host:"+server.toString()); System.out.println("sent on socket:"+sock); // Create the ACK packet UdpData ackData = new UdpData(4); ackData.putInt(4,0); // ACK opcode DatagramPacket ackPack = ackData.mkPacket(server,2000); // Create a packet to receive the data UdpData recData = new UdpData(516); // 516==max pak len pack = recData.mkPacket(); System.out.println("receiving packet"); for(int pakLen=516; pakLen==516; ) { sock.receive(pack); pakLen=pack.getLength(); System.out.println("still...."+sock.toString()); if (recData.getInt(0)==3) { // If a DATA pak then... blockNum=recData.getInt(2); outFile.write(recData.getData(),4,pakLen-4); ackData.putInt(blockNum,2); ackPack = ackData.mkPacket(server,pack.getPort()); sock.send(ackPack); } else throw new Exception(); }; outFile.close(); sock.close(); } catch (Exception e) { System.out.println("tftp session failed"); } } } 2)tftpServer: import java.net.*; import java.io.*; import java.util.*; public class tftpServer { // Tftp opcodes (RFC 1350) public static final int tftpRRQ=1; public static final int tftpWRQ=2; public static final int tftpDATA=3; public static final int tftpACK=4; public static final int tftpERROR=5; public static final int maxTftpPakLen=516; public static void main(String argv[]) { try { DatagramSocket sock = new DatagramSocket(2000); System.out.println("Server Ready. Listening on port: "+sock.getLocalPort()); for(; { UdpData reqData = new UdpData(maxTftpPakLen); DatagramPacket reqPak = reqData.mkPacket(); System.out.println("ready to receive request"); sock.receive(reqPak); System.out.println("received request at socket:"+sock.toString()); if (reqData.getInt(0)==tftpRRQ) { System.out.println("Display this:"); System.out.println("Request from "+reqPak.getAddress()); tftpTransfer t = new tftpTransfer(reqPak); } } } catch(Exception e) { System.out.println("Server terminated"); } } } 3)tftpTransfer: import java.net.*; import java.io.*; import java.util.*; class tftpTransfer extends Thread { protected DatagramSocket sock; protected InetAddress clientIP; protected int clientPort; protected FileInputStream source; protected UdpData dataPak; public tftpTransfer(DatagramPacket reqPak) { try { sock = new DatagramSocket(); clientIP = reqPak.getAddress(); clientPort = reqPak.getPort(); UdpData reqData = new UdpData(reqPak); File srcFile = new File(reqData.getString(2)); if (srcFile.exists() && srcFile.isFile() && srcFile.canRead()) { source = new FileInputStream(srcFile); dataPak = new UdpData(516); // 516==max pak len dataPak.putInt(3,0); // 3==DATA opcode this.start(); } } catch (Exception e) { System.out.println("Client failed"); }; } public void run() { int bytesRead = 512; DatagramPacket ack = new DatagramPacket(new byte[4],4); try { for (int blkNum=0; bytesRead==512; blkNum++) { // 512==max data len dataPak.putInt(blkNum,2); bytesRead = source.read(dataPak.getData(),4,512); sock.send(dataPak.mkPacket(clientIP,clientPort,516)); // 516==max data len + header sock.receive(ack); } } catch (Exception e) { System.out.println("Client failed"); } try { source.close(); sock.close(); } catch (Exception e) {}; } } 4)UdpData.java: import java.net.*; import java.io.*; import java.util.*; public class UdpData { private byte data[]; public UdpData(int len) { data = new byte[len]; }; public UdpData(DatagramPacket pack) { data = pack.getData(); } public byte[] getData() { return data; }; public int length() { return data.length; }; public DatagramPacket mkPacket() { return new DatagramPacket(data,data.length); }; public DatagramPacket mkPacket(int len) { return new DatagramPacket(data,len); }; public DatagramPacket mkPacket(InetAddress dest, int port) { return new DatagramPacket(data,data.length,dest,port); }; public DatagramPacket mkPacket(InetAddress dest, int port, int len) { return new DatagramPacket(data,len,dest,port); }; public int getInt(int offset) { // Fix to avoid sign extension // Remember what the MSB is and then turn it off to avoid sign extension. It is // then added back to the sum after everything has been converted to integers. byte lo = data[offset+1]; int signBit = (int)(lo&0x80); lo&=0x7f; // Standard TCP/IP byte order is hiByte followed by loByte (big endian) int hiByte = (int)data[offset]; int loByte = (int)lo; return (hiByte<<8)+signBit+loByte; }; public void putInt(int val, int offset) { int loByte = val%256; int hiByte = val>>>8; // Standard TCP/IP byte order is hiByte followed by loByte (big endian) data[offset] = (byte)hiByte; data[offset+1] = (byte)loByte; }; public String getString(int offset) { StringBuffer strBuf = new StringBuffer(); int curPos = offset; while (data[curPos]!=0) { strBuf.append((char)data[curPos]); curPos++; } return new String(strBuf); }; public void putString(String str, int offset) { str.getBytes(0,str.length(),data,offset); data[offset+str.length()]=0; }; } BUT I STILL CAN'T GET IT TO WORK.THE CLIENT IS SENDING A REQUEST FOR A FILE FROM THE SERVER AND IT JUST HANGS.THE SERVER IS UP AND WAITING FOR REQUESTS.
CAN ANYONE HELP ME WITH THIS??? THANKS A LOT, KICHU
Kichu, please do not post the same topic in multiple forums. Closing this. Respondents may answer here TFTP .
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher