Guest User

Untitled

a guest
Apr 23rd, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.26 KB | None | 0 0
  1. // 4-15-18
  2. // Client
  3.  
  4. import java.net.*;
  5. import java.io.*;
  6. import java.util.*;
  7. import java.nio.charset.*;
  8. import java.time.LocalTime;
  9. import java.nio.file.*;
  10. import static java.nio.file.StandardOpenOption.CREATE;
  11. import static java.nio.file.StandardOpenOption.APPEND;
  12.  
  13. public class Client
  14. {
  15. public static int serverPort = 69;
  16. public static int blockNumber = 0;
  17. public static String serverAddress;
  18. public static int timeouts = 0;
  19. public static int missedPackets = 0;
  20. public static int clientPort = 0;
  21. public static FileInputStream fileStream;
  22. public static String fileString;
  23. public static final int TIMEOUTS_MAX = 6;
  24. public static final int MISSED_PACKET_MAX = 6;
  25. public static final int BUFFER_SIZE = 516;
  26. public static final int TIMEOUT_INTERVAL = 2000;
  27.  
  28. public static final boolean DEBUG = false;
  29.  
  30. public static void main(String args[])
  31. {
  32. if(args.length != 3 && args.length != 4)
  33. {
  34. System.out.println("Improper argument length. Correct options are:\n\t <host> <PUT|GET> <file> [binary]");
  35. return;
  36. }
  37.  
  38. serverAddress = args[0];
  39. String operation = args[1].toUpperCase();
  40. String fileName = args[2];
  41. String mode = "netascii";
  42. if(!"PUT".equals(operation) && !"GET".equals(operation))
  43. {
  44. System.out.println(String.format("Could not handle \'operation\' %s\nAccepted operations are:\n\tPUT\tGET\n",operation));
  45. return;
  46. }
  47.  
  48. File file = new File(fileName);
  49. long fileSize = 0;
  50. if("PUT".equals(operation))
  51. {
  52. if(!file.exists() || file.isDirectory())
  53. {
  54. System.out.println(String.format("Could not handle request\n\t%s\ndoes not exist", fileName));
  55. return;
  56. }
  57. fileSize = file.length();
  58. if(fileSize > 65536 * 512)
  59. {
  60. System.out.println("\nFile over maximum per protocol. Consider packaging file into 32MB archives.");
  61. //return;
  62. }
  63. }
  64.  
  65. if(args.length == 4)
  66. if("binary".equals(args[3]))
  67. {
  68. mode = "octet";
  69. try{fileStream = new FileInputStream(file);}
  70. catch(Exception e)
  71. {
  72. debug(e.toString());
  73. }
  74. }
  75. else
  76. {}
  77. else
  78. {
  79. try
  80. {
  81. String str = new String(Files.readAllBytes(Paths.get(fileName)));
  82. char[] fileChar = str.toCharArray();
  83. for(int index = 0; index<fileChar.length; index++)
  84. {
  85. if((int) fileChar[index] == 13 && (int) fileChar[index+1] != 10)
  86. fileString += (char) 13 + (char) 10;
  87. else
  88. fileString += fileChar[index];
  89. }
  90. fileString = fileString.substring(3,fileString.length());
  91. }
  92. catch(Exception e)
  93. {
  94. debug(e.toString());
  95. }
  96. }
  97. byte OPCode;
  98. if("GET".equals(operation))
  99. OPCode = 0x1;
  100. else
  101. {
  102. OPCode = 0x2;
  103. }
  104.  
  105. // Communications
  106.  
  107. byte[] receiveData = new byte[Client.BUFFER_SIZE];
  108. try
  109. {
  110. ByteArrayOutputStream sendStream = new ByteArrayOutputStream(Client.BUFFER_SIZE);
  111. ByteArrayOutputStream receiveStream = new ByteArrayOutputStream(Client.BUFFER_SIZE);
  112. int replyPort = 0;
  113. int randomPort = new Random().nextInt(65536-1023) + 1024;
  114. Client.clientPort = randomPort;
  115.  
  116. sendStream.write(0x0);
  117. sendStream.write(OPCode);
  118. sendStream.write(fileName.getBytes("US-ASCII"));
  119. sendStream.write(0x0);
  120. sendStream.write(mode.getBytes("US-ASCII"));
  121. sendStream.write(0x0);
  122.  
  123.  
  124. DatagramSocket client = new DatagramSocket(randomPort);
  125. client.setSoTimeout(Client.TIMEOUT_INTERVAL);
  126.  
  127. DatagramPacket receivedPacket = new DatagramPacket(receiveData, receiveData.length);
  128.  
  129. while(true)
  130. {
  131. try
  132. {
  133. send(sendStream.toByteArray(), client, Client.serverPort);
  134. client.receive(receivedPacket);
  135. replyPort = receivedPacket.getPort();
  136. receiveData = receivedPacket.getData();
  137. break;
  138. }
  139. catch(SocketTimeoutException e)
  140. {
  141. Client.timeouts++;
  142. if(Client.timeouts>Client.TIMEOUTS_MAX)
  143. {
  144. System.out.println("Maximum number of attempts reached. No ACK received");
  145. return;
  146. }
  147. System.out.println("\nTimed out, retrying...\nNumber of attemps: " + Client.timeouts);
  148. send(sendStream.toByteArray(), client, replyPort);
  149. }
  150. }
  151.  
  152. //debug("'" + new String(receiveData, "US-ASCII") + "'");
  153. int replyCode = receiveData[1];
  154. switch(replyCode)
  155. {
  156. case(5):
  157.  
  158. System.out.println("Error:\n\t" + new String(Arrays.copyOfRange(receiveData, 4, receiveData.length), StandardCharsets.US_ASCII));
  159. return;
  160.  
  161.  
  162.  
  163. case(4):
  164. if(0x2 == OPCode)
  165. {
  166. // State information
  167.  
  168. debug("Acknowledged write request");
  169. int blockOne = 1;
  170. int blockTwo = 0;
  171. int sentData = 0;
  172. byte[] lastSentPacket = sendStream.toByteArray();
  173. byte[] lastReceivedPacket = receiveData;
  174. //Date date = new Date();
  175. long start = new Date().getTime();
  176. int dataInterval = 0;
  177. double rate = 0;
  178. while(sentData < fileSize)
  179. {
  180. Client.timeouts = 0;
  181. missedPackets = 0;
  182.  
  183. debug("Creating packet");
  184. sendStream.reset();
  185. sendStream.write(0x0);
  186. sendStream.write(0x3);
  187. sendStream.write((byte) blockTwo);
  188. sendStream.write((byte) blockOne);
  189. read(sendStream, mode);
  190. debug(""+sendStream.size());
  191. sentData += sendStream.size() - 4; // Don't do buffer size because of last f
  192. dataInterval += sendStream.size() - 4;
  193. if(blockOne % 50 == 0)
  194. {
  195. start = new Date().getTime();
  196. dataInterval = 0;
  197. }
  198. if(blockOne % 50 == 49)
  199. rate = (double) dataInterval / (new Date().getTime() - start);
  200.  
  201. if(blockOne % 100 == 0)
  202. {
  203. String status = String.format("\rStatus:\t%.2f%%", (double) sentData/fileSize*100);
  204. status += String.format("\t\tRate: \t%.0fkbps", rate);
  205. status += String.format("\t\tBlock: \t%h", (blockTwo * 128 + blockOne));
  206. System.out.print(status);
  207. }
  208.  
  209. debug("Sending data now");
  210. send(sendStream.toByteArray(), client, replyPort);
  211. lastSentPacket = sendStream.toByteArray();
  212.  
  213. while(true)
  214. {
  215. try
  216. {
  217. client.receive(receivedPacket);
  218. receiveData = receivedPacket.getData();
  219. lastReceivedPacket = receiveData;
  220.  
  221. // TFTP resets at 128 to block 63 ???
  222. //if(block==128 && receiveData[3] == 63)
  223. // block = 62;
  224.  
  225. replyPort = receivedPacket.getPort();
  226. break;
  227. }
  228. catch(SocketTimeoutException e)
  229. {
  230. Client.timeouts++;
  231. if(Client.timeouts>Client.TIMEOUTS_MAX)
  232. {
  233. System.out.println("Maximum number of attempts reached. Ending program.");
  234. return;
  235. }
  236. System.out.println("\nTimed out, retrying...\nNumber of attemps: " + Client.timeouts);
  237. send(lastSentPacket, client, replyPort);
  238.  
  239. }
  240. }
  241.  
  242. if(receiveData[3] != blockOne || receiveData[2] != blockTwo)
  243. {
  244. if(receiveData[1] == 5)
  245. {
  246. System.out.println("Error:\n\t" + new String(Arrays.copyOfRange(receiveData, 4, receiveData.length), StandardCharsets.US_ASCII));
  247. return;
  248. }
  249.  
  250. if(receiveData[3] == blockOne - 1 && receiveData[2] == blockTwo)
  251. {
  252. while(true)
  253. {
  254. try
  255. {
  256. Client.missedPackets++;
  257. if(Client.missedPackets > Client.MISSED_PACKET_MAX)
  258. {
  259. System.out.println("Maximum number of missed packets reached. Ending program.");
  260. return;
  261. }
  262.  
  263. System.out.println("\nMissed packet...\n"+ Client.missedPackets + " missed packets");
  264. send(lastSentPacket, client, replyPort);
  265.  
  266. client.receive(receivedPacket);
  267. receiveData = receivedPacket.getData();
  268. lastReceivedPacket = receiveData;
  269.  
  270. /*
  271. if(block==128 && receiveData[3] == 63)
  272. block = 62;
  273. */
  274.  
  275. replyPort = receivedPacket.getPort();
  276. break;
  277. }
  278. catch(SocketTimeoutException e)
  279. {
  280. Client.timeouts++;
  281. if(Client.timeouts>Client.TIMEOUTS_MAX)
  282. {
  283. System.out.println("Maximum number of attempts reached. Ending program.");
  284. return;
  285. }
  286. System.out.println("Timed out, retrying...\nNumber of attemps: " + Client.timeouts);
  287. }
  288. }
  289. }
  290. }
  291. //System.out.println("\nBlock "+block+"\n");
  292.  
  293. if(blockOne == Integer.MAX_VALUE)
  294. {
  295. blockOne = 0;
  296. if(blockTwo == Integer.MAX_VALUE)
  297. {
  298. blockTwo = 0;
  299. }
  300. else
  301. {
  302. blockTwo++;
  303. }
  304. }
  305. else
  306. {
  307. blockOne++;
  308. if((byte) blockOne == 0 && (blockOne > 0 || blockTwo>0))
  309. blockTwo++;
  310. if(blockTwo + blockOne == 0xffff && fileStream.available() > 0)
  311. {
  312. System.out.println("\n\nMaximum transfer size reached. \nConsider packaging file into 32MB archives if errors occur.\n");
  313. }
  314. }
  315. }
  316.  
  317. System.out.println("\nFile transfer complete.");
  318.  
  319. }
  320. break;
  321.  
  322. case(3):
  323. if(OPCode == 1)
  324. {
  325. debug("Acknowledged write request");
  326. int blockOne = 1;
  327. int blockTwo = 0;
  328. int sentData = 0;
  329. byte[] lastSentPacket = sendStream.toByteArray();
  330. byte[] lastReceivedPacket = receiveData;
  331. //Date date = new Date();
  332. long start = new Date().getTime();
  333. int dataInterval = 0;
  334. double rate = 0;
  335.  
  336. Client.timeouts = 0;
  337. missedPackets = 0;
  338.  
  339. Files.deleteIfExists(Paths.get(fileName));
  340.  
  341. while(true)
  342. {
  343. //Acknowledgment Packet
  344. sendStream.reset();
  345. sendStream.write(0x0);
  346. sendStream.write(0x4);
  347. sendStream.write((byte) blockTwo);
  348. sendStream.write((byte) blockOne);
  349. write(receivedPacket, fileName, mode);
  350. while(true)
  351. {
  352. try
  353. {
  354. send(sendStream.toByteArray(), client, replyPort);
  355. lastSentPacket = sendStream.toByteArray();
  356.  
  357. client.receive(receivedPacket);
  358. receiveData = receivedPacket.getData();
  359. lastReceivedPacket = receiveData;
  360.  
  361. // TFTP resets at 128 to block 63 ???
  362. //if(block==128 && receiveData[3] == 63)
  363. // block = 62;
  364. if(Client.timeouts > 0)
  365. System.out.println("\nPacket received, continuing normal program execution.\n");
  366. break;
  367. }
  368. catch(SocketTimeoutException e)
  369. {
  370. Client.timeouts++;
  371. if(Client.timeouts>Client.TIMEOUTS_MAX)
  372. {
  373. System.out.println("Maximum number of attempts reached. Ending program.");
  374. return;
  375. }
  376. if(receivedPacket.getLength() < Client.BUFFER_SIZE && Client.timeouts == 1)
  377. System.out.println("\nLikely last data packet was sent. Size: " + (receivedPacket.getLength() - 4) + "\nDallying...");
  378. if(receivedPacket.getLength() == Client.BUFFER_SIZE)
  379. System.out.println("\nTimed out, retrying...\nNumber of attemps: " + Client.timeouts);
  380. }
  381. catch(Exception e)
  382. {
  383. System.out.println("Unhandled exception: " + e.toString());
  384. }
  385. }
  386. replyPort = receivedPacket.getPort();
  387. debug("\nReply port: "+replyPort);
  388.  
  389. if(blockOne == Integer.MAX_VALUE)
  390. {
  391. System.out.println("\nMax block value reached.\n");
  392. blockOne = 0;
  393. if(blockTwo == Integer.MAX_VALUE)
  394. {
  395. blockTwo = 0;
  396. }
  397. else
  398. {
  399. blockTwo++;
  400. }
  401. }
  402. else
  403. {
  404. blockOne++;
  405. if((byte) blockOne == 0 && (blockOne > 0 || blockTwo>0))
  406. blockTwo++;
  407. if(blockTwo + blockOne == 0xffff && fileStream.available() > 0)
  408. {
  409. System.out.println("\n\nMaximum transfer size reached. \nConsider packaging file into 32MB archives if errors occur.\n");
  410. }
  411. }
  412.  
  413. sentData += receivedPacket.getLength() - 4; // Don't do buffer size because of last f
  414. dataInterval += receivedPacket.getLength();
  415. if(blockOne % 50 == 0)
  416. {
  417. start = new Date().getTime();
  418. dataInterval = 0;
  419. }
  420. if(blockOne % 50 == 49)
  421. rate = (double) dataInterval / (new Date().getTime() - start);
  422.  
  423. if(blockOne % 100 == 0)
  424. {
  425. String status = String.format("\rStatus:\t%.2fkb", (double) sentData/1024);
  426. status += String.format("\t\tRate: \t%.0fkbps", rate);
  427. status += String.format("\t\tBlock: \t%h", (blockTwo * 128 + blockOne));
  428. System.out.print(status);
  429. }
  430.  
  431. debug("Sending data now");
  432. debug("Creating packet");
  433.  
  434. if(receiveData.length > Client.BUFFER_SIZE)
  435. {
  436. System.out.println("\nData over maximum packet size. Terminating program.");
  437. //Error Packet
  438. sendStream.reset();
  439. sendStream.write(0x0);
  440. sendStream.write(0x5);
  441. sendStream.write(0x0);
  442. sendStream.write(0x4);
  443. sendStream.write("Data sent over maximum size".getBytes());
  444. send(sendStream.toByteArray(), client, replyPort);
  445. return;
  446. }
  447.  
  448.  
  449. if(receiveData[3] != blockOne || receiveData[2] != blockTwo)
  450. {
  451. if(receiveData[1] == 5)
  452. {
  453. System.out.println("Error:\n\t" + new String(Arrays.copyOfRange(receiveData, 4, receiveData.length), StandardCharsets.US_ASCII));
  454. return;
  455. }
  456.  
  457. if(receiveData[3] == blockOne - 1 && receiveData[2] == blockTwo)
  458. {
  459. while(true)
  460. {
  461. try
  462. {
  463. Client.missedPackets++;
  464. if(Client.missedPackets > Client.MISSED_PACKET_MAX)
  465. {
  466. System.out.println("Maximum number of missed packets reached. Ending program.");
  467. return;
  468. }
  469.  
  470. System.out.println("\nMissed packet...\n"+ Client.missedPackets + " missed packets");
  471. send(lastSentPacket, client, replyPort);
  472.  
  473. client.receive(receivedPacket);
  474. receiveData = receivedPacket.getData();
  475. lastReceivedPacket = receiveData;
  476.  
  477. /*
  478. if(block==128 && receiveData[3] == 63)
  479. block = 62;
  480. */
  481.  
  482. replyPort = receivedPacket.getPort();
  483. break;
  484. }
  485. catch(SocketTimeoutException e)
  486. {
  487. Client.timeouts++;
  488. if(Client.timeouts>Client.TIMEOUTS_MAX)
  489. {
  490. System.out.println("Maximum number of attempts reached. Ending program.");
  491. return;
  492. }
  493. System.out.println("Timed out, retrying...\nNumber of attemps: " + Client.timeouts);
  494. }
  495. }
  496. }
  497. }
  498. }
  499. }
  500. else
  501. {
  502. sendStream.reset();
  503. sendStream.write(0x0);
  504. sendStream.write(0x3);
  505. sendStream.write(0x0);
  506. sendStream.write(0x5);
  507. sendStream.write(0x0);
  508. sendStream.write(0x4);
  509. sendStream.write("Client does not support operation".getBytes("US-ASCII"));
  510. System.out.print("Data request denied");
  511. send(sendStream.toByteArray(), client, replyPort);
  512. }
  513. break;
  514.  
  515. default:
  516. System.out.println("\nInvalid OPCode.");
  517. //Error Packet
  518. sendStream.reset();
  519. sendStream.write(0x0);
  520. sendStream.write(0x5);
  521. sendStream.write(0x0);
  522. sendStream.write(0x4);
  523. sendStream.write("Invalid OPCode".getBytes());
  524. send(sendStream.toByteArray(), client, replyPort);
  525. return;
  526. }
  527.  
  528. }
  529. catch(Exception e)
  530. {
  531. debug(e.toString());
  532. }
  533. return;
  534. }
  535.  
  536.  
  537.  
  538. public static void read(ByteArrayOutputStream sendStream, String mode)
  539. {
  540. switch(mode)
  541. {
  542. case "octet":
  543. try
  544. {
  545. int b = 0;
  546. while(sendStream.size() < Client.BUFFER_SIZE)
  547. {
  548. if((b = fileStream.read()) > -1)
  549. {
  550. sendStream.write(b);
  551. }
  552. else
  553. {
  554. break;
  555. }
  556. }
  557. }
  558. catch(Exception e)
  559. {
  560. debug(e.toString());
  561. }
  562. debug("Last bit read");
  563. break;
  564.  
  565. case "netascii":
  566. try
  567. {
  568. int b = 0;
  569. while(sendStream.size() < Client.BUFFER_SIZE)
  570. {
  571. if(fileString.length() < 2)
  572. break;
  573. fileString = fileString.substring(1,fileString.length());
  574. sendStream.write(fileString.substring(0,1).getBytes("US-ASCII"));
  575. }
  576. }
  577. catch(Exception e)
  578. {
  579. debug(e.toString());
  580. }
  581.  
  582. break;
  583.  
  584. default:
  585. System.out.println("Invalid mode specified");
  586. return;
  587.  
  588. }
  589.  
  590. }
  591.  
  592. public static void write(DatagramPacket packet, String fileName, String mode)
  593. {
  594. byte[] byteData = packet.getData();
  595.  
  596.  
  597. switch(mode)
  598. {
  599.  
  600. case("octet"):
  601. try(FileOutputStream fos = new FileOutputStream(fileName, true);)
  602. {
  603. fos.write(Arrays.copyOfRange(byteData, 4, packet.getLength()));
  604. }
  605. catch(Exception e)
  606. {
  607. debug(e.toString());
  608. }
  609. break;
  610.  
  611.  
  612. case("netascii"):
  613. try(OutputStream out = new BufferedOutputStream(Files.newOutputStream(Paths.get(fileName), CREATE, APPEND));)
  614. {
  615. String data = new String(Arrays.copyOfRange(byteData, 4, packet.getLength()), "US-ASCII");
  616. data.replace(""+ (char) 13, ""+(char) 13 + (char) 10);
  617. debug(data);
  618. out.write(data.getBytes());
  619. }
  620. catch(Exception e)
  621. {
  622. debug(e.toString());
  623. }
  624. break;
  625.  
  626. // Should never be reached, mode is handled by client
  627. default:
  628.  
  629. System.out.println("\nUnspecified mode. Terminating Program.");
  630. /*
  631. sendStream.reset();
  632. sendStream.write(0x0);
  633. sendStream.write(0x5);
  634. sendStream.write(0x0);
  635. sendStream.write(0x4);
  636. sendStream.write("Unhandled transfer mode".getBytes());
  637. send(sendStream.toByteArray(), client, replyPort);
  638. */
  639. return;
  640. }
  641. }
  642.  
  643. public static void send(byte[] response, DatagramSocket client, int port)
  644. {
  645. try
  646. {
  647. InetAddress IP = InetAddress.getByName(Client.serverAddress);
  648. DatagramPacket packetToSend = new DatagramPacket(
  649. response,
  650. response.length,
  651. IP,
  652. port
  653. );
  654. client.send(packetToSend);
  655. }
  656. catch(Exception e)
  657. {
  658. System.out.println(e.toString());
  659. }
  660. }
  661.  
  662. public static void debug(String output)
  663. {
  664. if(Client.DEBUG)
  665. System.out.println(output);
  666. }
  667.  
  668. public static void debug(byte[] array)
  669. {
  670. if(Client.DEBUG)
  671. {
  672. String debug = "";
  673. for(int x = 0; x < array.length; x++)
  674. {
  675. debug += " " + array[x];
  676. }
  677.  
  678. System.out.println(debug);
  679. }
  680. }
  681. }
Add Comment
Please, Sign In to add comment