Advertisement
kiah

Untitled

Mar 4th, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.07 KB | None | 0 0
  1.  
  2. import java.io.*;
  3. import java.net.*;
  4. import java.nio.ByteBuffer;
  5.  
  6. public class TFTPServer {
  7. public static final int TFTPPORT = 4970;
  8. public static final int BUFSIZE = 516;
  9. public static final String READDIR = "/home/username/read/"; //custom address at your PC
  10. public static final String WRITEDIR = "/home/username/write/"; //custom address at your PC
  11. // OP codes
  12. public static final int OP_RRQ = 1;
  13. public static final int OP_WRQ = 2;
  14. public static final int OP_DAT = 3;
  15. public static final int OP_ACK = 4;
  16. public static final int OP_ERR = 5;
  17. public static String Mode;
  18. public static final int OP_ERR0 = 0;
  19. public static String ERR0 = "Not defined, see error message(if any)";
  20. public static final int OP_ERR1 = 1;
  21. public static String ERR1 = "File not found.";
  22. public static final int OP_ERR2 = 2;
  23. public static String ERR2 = "Access Violation";
  24. public static final int OP_ERR3 = 3;
  25. public static String ERR3 = "Disk full of allocation exceeded";
  26. public static final int OP_ERR4 = 4;
  27. public static String ERR4 = "Illegal TFTP operation";
  28. public static final int OP_ERR5 = 5;
  29. public static String ERR5 = "Unknown transfer ID";
  30. public static final int OP_ERR6 = 6;
  31. public static String ERR6 = "File already exists";
  32.  
  33. public static void main(String[] args) {
  34. if (args.length > 0) {
  35. System.err.printf("usage: java %s\n", TFTPServer.class.getCanonicalName());
  36. System.exit(1);
  37. }
  38. //Starting the server
  39. try {
  40. TFTPServer server = new TFTPServer();
  41. server.start();
  42. } catch (SocketException e) {
  43. e.printStackTrace();
  44. }
  45. }
  46.  
  47. private void start() throws SocketException {
  48. byte[] buf = new byte[BUFSIZE];
  49.  
  50. // Create socket
  51. DatagramSocket socket = new DatagramSocket(null);
  52.  
  53. // Create local bind point
  54. SocketAddress localBindPoint = new InetSocketAddress(TFTPPORT);
  55. socket.bind(localBindPoint);
  56.  
  57. System.out.printf("Listening at port %d for new requests\n", TFTPPORT);
  58.  
  59. // Loop to handle client requests
  60. while (true) {
  61.  
  62. final InetSocketAddress clientAddress = receiveFrom(socket, buf);
  63.  
  64. // If clientAddress is null, an error occurred in receiveFrom()
  65. if (clientAddress == null)
  66. continue;
  67.  
  68. final StringBuffer requestedFile = new StringBuffer();
  69. final int reqtype = ParseRQ(buf, requestedFile);
  70.  
  71. new Thread() {
  72. public void run() {
  73. try {
  74. DatagramSocket sendSocket = new DatagramSocket(0);
  75.  
  76. // Connect to client
  77. sendSocket.connect(clientAddress);
  78.  
  79. System.out.printf("%s request for %s from %s using port %d\n",
  80. (reqtype == OP_RRQ) ? "Read" : "Write",
  81. clientAddress.getHostName(), clientAddress.getPort());
  82.  
  83. // Read request
  84. if (reqtype == OP_RRQ) {
  85. requestedFile.insert(0, READDIR);
  86. HandleRQ(sendSocket, requestedFile.toString(), OP_RRQ);
  87. }
  88. // Write request
  89. else {
  90. requestedFile.insert(0, WRITEDIR);
  91. HandleRQ(sendSocket, requestedFile.toString(), OP_WRQ);
  92. }
  93. sendSocket.close();
  94. } catch (SocketException e) {
  95. e.printStackTrace();
  96. }
  97. }
  98. }.start();
  99. }
  100. }
  101.  
  102. /**
  103. * Reads the first block of data, i.e., the request for an action (read or write).
  104. *
  105. * @param socket (socket to read from)
  106. * @param buf (where to store the read data)
  107. * @return socketAddress (the socket address of the client)
  108. */
  109. private InetSocketAddress receiveFrom(DatagramSocket socket, byte[] buf) {
  110. // Create datagram packet
  111. DatagramPacket receivePacket = new DatagramPacket(buf, buf.length);
  112.  
  113. // Receive packet
  114. try {
  115. socket.receive(receivePacket);
  116. } catch (IOException e) {
  117. System.out.println("Error: " + e);
  118. }
  119.  
  120. // Get client address and port from the packet
  121. InetSocketAddress socketAddress = new InetSocketAddress(receivePacket.getAddress(), receivePacket.getPort());
  122. return socketAddress;
  123. }
  124.  
  125. /**
  126. * Parses the request in buf to retrieve the type of request and requestedFile
  127. *
  128. * @param buf (received request)
  129. * @param requestedFile (name of file to read/write)
  130. * @return opcode (request type: RRQ or WRQ)
  131. */
  132. private int ParseRQ(byte[] buf, StringBuffer requestedFile) {
  133. // See "TFTP Formats" in TFTP specification for the RRQ/WRQ request contents
  134. // byte[] buf;
  135. ByteBuffer wrap = ByteBuffer.wrap(buf);
  136. short opcode = wrap.getShort();
  137. String file = requestedFile.toString();
  138.  
  139. file = file.substring(2, requestedFile.length());
  140. String[] parts = file.split("0");
  141. String fileName = (parts[0]);
  142.  
  143. String Mode = parts[1];
  144. System.out.println("Opcode is: " + opcode);
  145. System.out.println("Requested file: " + fileName);
  146. System.out.println("Transfer mode is: " + Mode);
  147. return opcode;
  148. }
  149.  
  150. /**
  151. * Handles RRQ and WRQ requests
  152. *
  153. * @param sendSocket (socket used to send/receive packets)
  154. * @param requestedFile (name of file to read/write)
  155. * @param opcode (RRQ or WRQ)
  156. */
  157. private void HandleRQ(DatagramSocket sendSocket, String requestedFile, int opcode) {
  158. System.out.println("Requested file: " + requestedFile);
  159. File file = new File(requestedFile);
  160.  
  161. if (opcode == OP_RRQ) {
  162. // See "TFTP Formats" in TFTP specification for the DATA and ACK packet contents
  163.  
  164. FileInputStream in = null;
  165.  
  166. try {
  167. in = new FileInputStream(requestedFile);
  168.  
  169. if (send_DATA_receive_ACK(sendSocket, in)) {
  170. System.out.println("Sending...");
  171. //System.out.println("Successfully sent. BlockNum is: " + blockNum);
  172. } else {
  173. System.out.println("ERROR: Connection lost");
  174. send_ERR(sendSocket, OP_ERR0, "Connection to server lost");
  175. }
  176. } catch (FileNotFoundException f) {
  177. System.out.println("ERROR, FILE NOT FOUND" + f);
  178. send_ERR(sendSocket, OP_ERR1, ERR1);
  179. }
  180. }
  181. else if (opcode == OP_WRQ) {
  182. if (file.exists()) {
  183. System.out.println("Error, file already exists");
  184. send_ERR(sendSocket, OP_ERR6, ERR6);
  185. } else {
  186.  
  187. short blockNum = 0;
  188. ByteBuffer buffer = ByteBuffer.allocate(BUFSIZE);
  189. buffer.putInt(OP_ACK);
  190. buffer.putShort(blockNum);
  191. DatagramPacket ackP = new DatagramPacket(buffer.array(), 4);
  192.  
  193. boolean result = receive_DATA_send_ACK(sendSocket, ackP, blockNum);
  194.  
  195. while (result) {
  196. try {
  197. FileOutputStream out = new FileOutputStream(file);
  198. } catch (FileNotFoundException e) {
  199. send_ERR(sendSocket, OP_ERR3, "Could not create file.");
  200.  
  201. }
  202. }
  203. }
  204. }
  205. else {
  206. System.err.println("Invalid request. Sending an error packet.");
  207. // See "TFTP Formats" in TFTP specification for the ERROR packet contents
  208. send_ERR(sendSocket, opcode, "Invalid request. Sending an error packet.");
  209. }
  210. }
  211.  
  212. /**
  213. * To be implemented
  214. */
  215. private boolean send_DATA_receive_ACK(DatagramSocket sendSocket, FileInputStream in ) {
  216. short blockNum = 1;
  217. byte[] buf = new byte[512];
  218. int length=0;
  219. try
  220. {length = in.read(buf);}
  221. catch(IOException e)
  222. {System.out.println("ERROR IOE "+e);}
  223.  
  224. ByteBuffer wrap = ByteBuffer.wrap(buf);
  225. short shortVal = OP_DAT;
  226.  
  227. // put the opcode and block number in the bytebuffer
  228. wrap.putShort(shortVal);
  229. wrap.putShort(blockNum);
  230. wrap.put(buf, 0, length);
  231. byte[] wrapArr =wrap.array();
  232.  
  233. int waitTimeForAck = 10; //staring with 10 milliseconds
  234.  
  235. //The Send DATA part
  236. DatagramPacket sender = new DatagramPacket(wrapArr, 4+length);
  237.  
  238.  
  239. byte[] ACKreceived = new byte[4]; //The ACK received is 2 byte (opt) + 2 byte (block) = 4
  240. DatagramPacket receivedACKPacket = new DatagramPacket(ACKreceived, ACKreceived.length);
  241. try {
  242. sendSocket.send(sender);
  243. sendSocket.setSoTimeout(waitTimeForAck);
  244. }
  245. catch(IOException e)
  246. {
  247. System.out.println("ERROR SENDING PACKET "+e);
  248. }
  249.  
  250. try{
  251.  
  252. sendSocket.receive(receivedACKPacket);} catch(IOException e){
  253. System.err.println("No acknowledgment packet received!");
  254. e.printStackTrace();
  255. return false;
  256. }
  257.  
  258. return true;
  259. }
  260.  
  261. private boolean receive_DATA_send_ACK(DatagramSocket sendSocket, DatagramPacket ackP, short block) {
  262.  
  263. byte[]rec=new byte[BUFSIZE];
  264. DatagramPacket recD= new DatagramPacket(rec, rec.length);
  265. try {
  266. sendSocket.receive(recD);
  267. ByteBuffer buffer = ByteBuffer.wrap(recD.getData());
  268. int opcode = buffer.getInt();
  269. short blockNum = buffer.getShort();
  270. System.out.println("Block recieved: "+ blockNum +" Block sent?: "+ block);
  271. sendSocket.send(ackP);
  272. // out.write(recD.getData(), 4, recD.length - 4);
  273.  
  274. } catch (FileNotFoundException f) {
  275. System.out.println("ERROR, file could not be created" + f);
  276. send_ERR(sendSocket, OP_ERR0, "ERROR: FIle could not be created");
  277. }
  278. catch(IOException e) {
  279. System.out.println("Error in sending Ack: "+e);
  280.  
  281. }
  282. return true;
  283. }
  284.  
  285.  
  286.  
  287. private void send_ERR(DatagramSocket sendSocket, int opcode, String msg)
  288. {
  289. ByteBuffer err = ByteBuffer.allocate(BUFSIZE);
  290. err.put((byte) 0);
  291. err.putInt(OP_ERR);
  292. err.putInt(opcode);
  293. err.put((byte) 0);
  294. err.put(msg.getBytes());
  295. err.put((byte) 0);
  296. byte[] error=err.array();
  297. DatagramPacket errorP = new DatagramPacket(error, error.length);
  298. try {
  299. sendSocket.send(errorP);
  300. } catch (IOException e) {
  301. System.err.println("ERROR WITH ERROR: Error packet did not send");
  302. }
  303.  
  304. }
  305.  
  306. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement