package clientP2P; import exception.NotFound; import exception.ProtocolError; import exception.InternalError; import exception.TransmissionError; import java.util.Scanner; import java.net.InetAddress; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.io.File; import java.io.IOException; import java.io.FileWriter; /** Implementation of P2P-JAVA-PROJECT VERSION 1.0 protocol for UDP. * @author Louis Royer * @author Flavien Haas * @author JS Auge * @version 1.0 */ public class ClientManagementUDP implements Runnable { private String baseDirectory; private int UDPPort; private String host; private final String protocolID = "P2P-JAVA-PROJECT VERSION 1.0"; /** Constructor for UDP implementation, with baseDirectory and UDPPort parameters. * @param baseDirectory the root directory where files are stored * @param UDPPort the server will listen on this port */ public ClientManagementUDP(String baseDirectory, String host, int UDPPort) { this.baseDirectory = baseDirectory; this.host = host; this.UDPPort = UDPPort; } /** Implementation of Runnable */ public void run() { System.out.println("Files present on the server:"); try { String msg = sendMsg(sendListDirectoryRequest()); System.out.println(listDirectory(msg)); System.out.println("Name of the file to download:"); Scanner scanner = new Scanner(System.in); String f = scanner.nextLine(); msg = sendMsg(sendDownloadRequest(f)); download(msg, f); } catch (TransmissionError e) { System.out.println("Transmission error"); } catch (ProtocolError e) { System.out.println("Protocol error"); } catch (NotFound e) { System.out.println("File not found"); } catch (InternalError e) { System.out.println("Server internal error"); } catch (IOException e) { System.out.println("Cannot write to file"); } } /** Prepare request to download file * @param filename name of the file to be downloaded * @return request to be send */ private String sendDownloadRequest(String filename) { return protocolID + "\nDOWNLOAD\n" + filename + "\n"; } /** Download file. * @param response Servers's response * @throws NotFound * @throws ProtocolError * @throws InternalError */ private void download(String response, String filename) throws TransmissionError, NotFound, ProtocolError, InternalError, IOException { try { String r[] = response.split("\n"); checkProtocolID(r[0]); switch (r[1]) { case "LOAD": int size = Integer.parseInt(r[2]); if (r[3].length() != size - 1) { throw new TransmissionError(); } FileWriter fileWriter = new FileWriter(baseDirectory + filename); fileWriter.write(r[3]); fileWriter.close(); break; case "NOT FOUND": throw new NotFound(); case "INTERNAL ERROR": throw new InternalError(); default: System.out.println("Error: Unknow format `" + r[1] + "`"); throw new ProtocolError(); } } catch (java.lang.ArrayIndexOutOfBoundsException e) { System.out.println("Error: IndexOutOfBonds"); throw new ProtocolError(); } catch (NumberFormatException e) { System.out.println("Error: NumberFormat"); throw new ProtocolError(); } } /** Prepare request to list files on server * @return request to be send */ private String sendListDirectoryRequest() { return protocolID + "\nLIST\n"; } /** Parse list of directory response from server * @param response server's response * @return list of files, separated by CRLF * @throws ProtocolError */ private String listDirectory(String response) throws ProtocolError { try { String r[] = response.split("\n"); checkProtocolID(r[0]); return response.split(protocolID + "\nLIST\n")[1].split("\n\n")[0]; } catch (java.lang.ArrayIndexOutOfBoundsException e) { throw new ProtocolError(); } } /** Check client's protocol identifier matches message's protocol identifier. * Throws a ProtocolError if mismatched. * @param msgProtocolID part of the request containing protocol identifier * @throws ProtocolError */ private void checkProtocolID(String msgProtocolID) throws ProtocolError { if (!protocolID.equals(msgProtocolID)) { throw new ProtocolError(); } } /** Send message to server * @param msg message to be send * @return server's response */ private String sendMsg(String msg) throws TransmissionError { //TODO changer le gros try catch try{ InetAddress dst = InetAddress.getByName(host); byte [] buffer = msg.getBytes(); byte [] buffer2 = new byte[1500]; DatagramSocket socket = new DatagramSocket(); DatagramPacket reception = new DatagramPacket(buffer2, 1500); DatagramPacket emission = new DatagramPacket(buffer, buffer.length, dst, UDPPort); socket.send(emission); socket.receive(reception); return new String(reception.getData(), 0, reception.getLength()); } catch (Exception e){ System.out.println(e); throw new TransmissionError(); } } }