diff --git a/src/exception/InternalError.class b/src/exception/InternalError.class new file mode 100644 index 0000000..90c81e9 Binary files /dev/null and b/src/exception/InternalError.class differ diff --git a/src/exception/NotFound.class b/src/exception/NotFound.class new file mode 100644 index 0000000..6e896f4 Binary files /dev/null and b/src/exception/NotFound.class differ diff --git a/src/exception/ProtocolError.class b/src/exception/ProtocolError.class new file mode 100644 index 0000000..ab341e7 Binary files /dev/null and b/src/exception/ProtocolError.class differ diff --git a/src/serverP2P/ServerManagementUDP.class b/src/serverP2P/ServerManagementUDP.class new file mode 100644 index 0000000..da550c6 Binary files /dev/null and b/src/serverP2P/ServerManagementUDP.class differ diff --git a/src/serverP2P/ServerManagementUDP.java b/src/serverP2P/ServerManagementUDP.java new file mode 100644 index 0000000..2eddedc --- /dev/null +++ b/src/serverP2P/ServerManagementUDP.java @@ -0,0 +1,175 @@ +package serverP2P; +import java.util.Vector; +import java.io.File; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import exception.ProtocolError; +import exception.NotFound; +import exception.InternalError; +import java.nio.file.Paths; +import java.nio.file.Files; + + +/** 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 ServerManagementUDP implements Runnable { + + private Vector fileList; + private String baseDirectory; + private int UDPPort; + 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 ServerManagementUDP(String baseDirectory, int UDPPort) { + this.baseDirectory = baseDirectory; + this.UDPPort = UDPPort; + fileList = new Vector(); + initFileList(); + } + + /** Implementation of runnable. This methods allows to run the server. + */ + public void run() { + try { + // socket creation on port UDPPort + DatagramSocket socket = new DatagramSocket(UDPPort); + // buffer to receive UDP Datagram + final byte[] buffer = new byte[1024]; + while(true) { + // java object to receive Datagram + DatagramPacket dgram = new DatagramPacket(buffer, buffer.length); + // wait and receive datagram + socket.receive(dgram); + // extract data + String str = new String(dgram.getData(), 0, dgram.getLength()); + // process request + str = processRequest(str); + dgram.setData(str.getBytes()); + dgram.setLength(str.getBytes().length); + // send response + socket.send(dgram); + } + } catch (Exception e) { + // TODO: treat exceptions + } + } + + /** Process the request received. + * @param request the request received + * @return data to be send as response + */ + String processRequest(String request) { + String res = protocolID + "\n"; + String formattedRequest[] = request.split("\n"); + try { + try { + checkProtocolID(formattedRequest[0]); + switch (formattedRequest[1]) { + case "LIST": + res += sendFileList(); + break; + case "DOWNLOAD": + res += upload(formattedRequest[2]); + break; + default: + throw new ProtocolError(); + } + } catch (java.lang.ArrayIndexOutOfBoundsException e) { + throw new ProtocolError(); + } + } catch (ProtocolError e) { + // wrong version or wrong implementation + res += sendProtocolError(); + } catch (InternalError e) { + res += sendInternalError(); + } catch (NotFound e) { + res += sendNotFound(); + } + return res; + } + + /** Initialize local list of all files allowed to be shared. + */ + private void initFileList() { + File folder = new File(baseDirectory); + File[] files = folder.listFiles(); + /* Add non-recursively files's names to fileList */ + for (int i = 0; i < files.length; i++) { + if (files[i].isFile()) { + fileList.add(files[i].getName()); + } + } + } + + /** Check server'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 != msgProtocolID) { + throw new ProtocolError(); + } + } + + /** Prepare the data to be send if a file is requested + * @param filename name of the file to be send + * @return data to be send + * @throws NotFound + * @throws InternalError + */ + private String upload(String filename) throws NotFound, InternalError { + File file = new File(filename); + if (!file.exists() || !file.isFile()) { + throw new NotFound(); + } + String res = "LOAD " + file.length() + "\n"; + try { + res += new String(Files.readAllBytes(Paths.get(filename))); + } catch (IOException e) { + throw new InternalError(); + } + return res; + } + + /** Prepare the data to be send if file list is requested + * @return data to be send + */ + private String sendFileList() { + String res = "LIST\n"; + for (String f : fileList) { + res += (f + '\n'); + } + return res + '\n'; + } + + /** Prepare data to be send if protocol error is detected + * @return data to be send + */ + private String sendProtocolError() { + return "PROTOCOL ERROR\n"; + } + + /** Prepare data to be send if file is not found + * @return data to be send + */ + private String sendNotFound() { + return "NOT FOUND\n"; + } + + /** Prepare data to be send if internal error encounterred + * @return data to be send + */ + private String sendInternalError() { + return "INTERNAL ERROR\n"; + } + +} diff --git a/src/serverP2P/ServerP2P.class b/src/serverP2P/ServerP2P.class new file mode 100644 index 0000000..aa96009 Binary files /dev/null and b/src/serverP2P/ServerP2P.class differ diff --git a/src/serverP2P/ServerP2P.java b/src/serverP2P/ServerP2P.java new file mode 100644 index 0000000..33338e3 --- /dev/null +++ b/src/serverP2P/ServerP2P.java @@ -0,0 +1,39 @@ +package serverP2P; +import java.io.File; +import serverP2P.ServerManagementUDP; + +public class ServerP2P { + private int port; + private String directory; + public ServerP2P() { + port = 40000; + String d; + /* Follow XDG Base Directory Specification + * https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html + */ + if (System.getProperty("os.name").equals("Linux")) { + d = System.getenv().get("XDG_DATA_HOME"); + if (d == null || d.equals("")) { + d = System.getenv().get("HOME"); + if (d != null && (!d.equals(""))) { + d += "/.local/share"; + } else { + d += "."; + } + } + } else { + d = "."; + } + d += "P2P_JAVA_PROJECT_SERVER/"; + // create directory if not already exists + new File(d).mkdirs(); + } + public static void main(String [] args) { + ServerP2P s = new ServerP2P(); + ServerManagementUDP sm = new ServerManagementUDP(s.directory, s.port); + Thread t = new Thread(sm); + t.setName("server P2P-JAVA-PROJECT"); + t.start(); + } + +}