From 07d92762326fb3cb85dc8d57a8daa968da659a36 Mon Sep 17 00:00:00 2001 From: Louis Date: Fri, 20 Mar 2020 00:11:13 +0100 Subject: [PATCH] Changes in protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit À implémenter: Register + Unregister dans protocolP2P. Encore des erreurs: - [UDP] ICMP Port unreachable, c’est parce qu’on essaie de se connecter à un port qui est fermé. c’est pour ça qu’il faut donner le port dans register et dans unregister (sinon on a le mauvais HostItem). - [TCP] une autre erreur que je corrigerai demain --- doc/protocol.md | 10 ++++++++ src/clientP2P/ClientP2P.java | 6 +++-- src/protocolP2P/ProtocolP2PPacketUDP.java | 6 +++-- src/serverP2P/ServerManagementTCP.java | 27 +++++++++++++++++++++- src/serverP2P/ServerManagementUDP.java | 28 +++++++++++++++++++++-- src/serverP2P/ServerP2P.java | 14 +++++++----- src/tools/HostItem.java | 21 ++++++++++++++++- src/tracker/TrackerManagementTCP.java | 10 ++++---- src/tracker/TrackerManagementUDP.java | 8 +++---- 9 files changed, 107 insertions(+), 23 deletions(-) diff --git a/doc/protocol.md b/doc/protocol.md index a01a6c9..352078f 100644 --- a/doc/protocol.md +++ b/doc/protocol.md @@ -106,11 +106,21 @@ A algo hash bloc contains: #### Register Used by a server to register itself on a tracker. Server may want to do a free `DISCOVER` to check if they have been registered. +Payload contains: + +``` +2 bytes: [] +``` #### Unregister Used by a server to unregister itself from a tracker. No error is raised if the server was not registered. Server may want to do a free `DISCOVER` to check if they have been unregistered. +Payload contains: + +``` +2 bytes: [] +``` #### Discover request If payload size is null, lists all servers registered. diff --git a/src/clientP2P/ClientP2P.java b/src/clientP2P/ClientP2P.java index 34a9519..e08c1fb 100644 --- a/src/clientP2P/ClientP2P.java +++ b/src/clientP2P/ClientP2P.java @@ -30,6 +30,7 @@ public class ClientP2P { private Directories directories; private List hostList; private static final int defaultPort = 20000; + private HostItem tracker; /** Initialize loggers if directories and logger are null, @@ -47,6 +48,7 @@ public class ClientP2P { * @param portStr String containing port for server listenning. */ public ClientP2P(String portStr) { + tracker = new HostItem("localhost", 30000); // TODO : make it configurable try{ port = Integer.valueOf(Integer.parseInt(portStr)); } catch (NumberFormatException e){ @@ -84,8 +86,8 @@ public class ClientP2P { } // Server threads - ServerManagementUDP smudp = new ServerManagementUDP(c.directories.getDataHomeDirectory() + subdir, c.port, c.loggerServer); - ServerManagementTCP smtcp = new ServerManagementTCP(c.directories.getDataHomeDirectory() + subdir, c.port, c.loggerServer); + ServerManagementUDP smudp = new ServerManagementUDP(c.directories.getDataHomeDirectory() + subdir, c.port, c.loggerServer, c.tracker); + ServerManagementTCP smtcp = new ServerManagementTCP(c.directories.getDataHomeDirectory() + subdir, c.port, c.loggerServer, c.tracker); Thread tudp = new Thread(smudp); tudp.setName("server UDP P2P-JAVA-PROJECT (port: " + c.port + ")"); tudp.start(); diff --git a/src/protocolP2P/ProtocolP2PPacketUDP.java b/src/protocolP2P/ProtocolP2PPacketUDP.java index db92d2f..500fa57 100644 --- a/src/protocolP2P/ProtocolP2PPacketUDP.java +++ b/src/protocolP2P/ProtocolP2PPacketUDP.java @@ -34,6 +34,7 @@ import java.io.IOException; public class ProtocolP2PPacketUDP extends ProtocolP2PPacket { private final static int CHECKSUM_POSITION = 2; + private HostItem remoteHost; private SocketAddress responseSocketAddress; // socket address used when receptionning request and to sending response private DatagramSocket responseSocket; // socket used to recept request and send response private DatagramSocket requestSocket; // socket used to send request and to reception response @@ -113,6 +114,7 @@ public class ProtocolP2PPacketUDP extends ProtocolP2PPacket { DatagramPacket reception = new DatagramPacket(packet, packet.length); ss.receive(reception); responseSocketAddress = reception.getSocketAddress(); + remoteHost = new HostItem(reception.getAddress().getHostName(), reception.getPort()); // contruction boolean protocolError = false; try { @@ -371,9 +373,9 @@ public class ProtocolP2PPacketUDP extends ProtocolP2PPacket { * @throws InternalError */ public HostItem getHostItem() throws InternalError { - if (responseSocket == null) { + if (remoteHost == null) { throw new InternalError(); } - return new HostItem(responseSocket.getInetAddress().getHostName(), responseSocket.getPort()); + return remoteHost; } } diff --git a/src/serverP2P/ServerManagementTCP.java b/src/serverP2P/ServerManagementTCP.java index 316143e..6001cdf 100644 --- a/src/serverP2P/ServerManagementTCP.java +++ b/src/serverP2P/ServerManagementTCP.java @@ -32,6 +32,7 @@ import remoteException.EmptyFile; import java.util.Arrays; import tools.Logger; import tools.LogLevel; +import tools.HostItem; import java.util.HashMap; import java.util.Map; import protocolP2P.HashAlgorithm; @@ -53,12 +54,14 @@ public class ServerManagementTCP implements Runnable { private int TCPPort; private ServerSocket socket; private Logger logger; + private HostItem tracker; /** Constructor for TCP implementation, with baseDirectory and TCPPort parameters. * @param baseDirectory the root directory where files are stored * @param TCPPort the server will listen on this port */ - public ServerManagementTCP(String baseDirectory, int TCPPort, Logger logger) { + public ServerManagementTCP(String baseDirectory, int TCPPort, Logger logger, HostItem tracker) { + this.tracker = tracker; this.logger = logger; this.baseDirectory = baseDirectory; this.TCPPort = TCPPort; @@ -79,6 +82,12 @@ public class ServerManagementTCP implements Runnable { */ public void run() { logger.writeTCP("Server sucessfully started", LogLevel.Info); + try { + registerTracker(); + } catch (Exception e) { + logger.writeTCP(e, LogLevel.Error); + System.exit(-4); + } do { try { Socket s = socket.accept(); @@ -332,4 +341,20 @@ public class ServerManagementTCP implements Runnable { } } + /** Register server on tracker + * @throws InternalError + * @throws IOException + * @throws SocketClosed + */ + public void registerTracker() throws InternalError, IOException, SocketClosed { + logger.writeTCP("Unregistering from tracker", LogLevel.Info); + ProtocolP2PPacket p = (ProtocolP2PPacket)new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.UNREGISTER)); + p.sendRequest((Object)tracker.getTCPSocket()); + logger.writeTCP("Registering into tracker", LogLevel.Info); + p = (ProtocolP2PPacket)new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.REGISTER)); + p.sendRequest((Object)tracker.getTCPSocket()); + logger.writeTCP("Registering completed", LogLevel.Debug); + tracker.closeTCPSocket(); + } + } diff --git a/src/serverP2P/ServerManagementUDP.java b/src/serverP2P/ServerManagementUDP.java index 3289796..0de0ef7 100644 --- a/src/serverP2P/ServerManagementUDP.java +++ b/src/serverP2P/ServerManagementUDP.java @@ -36,6 +36,7 @@ import java.util.Map; import protocolP2P.HashAlgorithm; import protocolP2P.HashRequest; import protocolP2P.HashResponse; +import tools.HostItem; /** Implementation of P2P-JAVA-PROJECT VERSION 1.0 protocol for UDP. * @author Louis Royer @@ -51,15 +52,17 @@ public class ServerManagementUDP implements Runnable { private int UDPPort; private DatagramSocket socket; private Logger logger; + private HostItem tracker; /** 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, Logger logger) { + public ServerManagementUDP(String baseDirectory, int UDPPort, Logger logger, HostItem tracker) { this.logger = logger; this.baseDirectory = baseDirectory; this.UDPPort = UDPPort; + this.tracker = tracker; initFileList(); initSha512(); try { @@ -74,6 +77,12 @@ public class ServerManagementUDP implements Runnable { */ public void run() { logger.writeUDP("Server sucessfully started", LogLevel.Info); + try { + registerTracker(); + } catch (Exception e) { + logger.writeUDP(e, LogLevel.Error); + System.exit(-4); + } while(true) { try { ProtocolP2PPacketUDP pd = new ProtocolP2PPacketUDP((Object)socket); @@ -268,5 +277,20 @@ public class ServerManagementUDP implements Runnable { } } } - + + /** Register server on tracker + * @throws InternalError + * @throws IOException + * @throws SocketClosed + */ + public void registerTracker() throws InternalError, IOException, SocketClosed { + logger.writeUDP("Unregistering from tracker", LogLevel.Info); + ProtocolP2PPacket p = (ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.UNREGISTER)); + p.sendRequest((Object)tracker.getUDPSocket()); + logger.writeUDP("Registering into tracker", LogLevel.Info); + p = (ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.REGISTER)); + p.sendRequest((Object)tracker.getUDPSocket()); + tracker.closeUDPSocket(); + logger.writeUDP("Registering completed", LogLevel.Debug); + } } diff --git a/src/serverP2P/ServerP2P.java b/src/serverP2P/ServerP2P.java index be8bfec..abfdb66 100644 --- a/src/serverP2P/ServerP2P.java +++ b/src/serverP2P/ServerP2P.java @@ -3,6 +3,7 @@ import serverP2P.ServerManagementUDP; import serverP2P.ServerManagementTCP; import tools.Directories; import tools.Logger; +import tools.HostItem; /** Server only implementation * First argument of main method is port listened by the server, and is mandatory. @@ -16,12 +17,14 @@ public class ServerP2P { private Directories directories; static private final String subdir = "seeded/"; private Logger logger; + private HostItem tracker; /** Constructor with portStr containing a port number. * @param portStr String containing port number of listening. */ - public ServerP2P(String portStr) { + public ServerP2P(String portStr, String trackerHostname, String trackerPortStr) { port = Integer.valueOf(Integer.parseInt(portStr)); + tracker = new HostItem(trackerHostname, Integer.valueOf(Integer.parseInt(trackerPortStr))); directories = new Directories("P2P_JAVA_PROJECT_SERVER_" + port); directories.createSubdir(subdir); logger = new Logger(directories.getDataHomeDirectory() + "server.log"); @@ -31,18 +34,17 @@ public class ServerP2P { /** Main program entry point * first parameter is port number and is mandatory - * to test, run with: java -ea serverP2P.ServerP2P -- + * to test, run with: java -ea serverP2P.ServerP2P -- * @param args parameters */ public static void main(String [] args) { - if (args[1].equals("help") || args[1].equals("-h") || args[1].equals("h")){ System.out.println("usage : java -ea serveurP2P.ServeurP2P -- "); } else{ - ServerP2P s = new ServerP2P(args[1]); - ServerManagementUDP smudp = new ServerManagementUDP(s.directories.getDataHomeDirectory() + subdir, s.port, s.logger); - ServerManagementTCP smtcp = new ServerManagementTCP(s.directories.getDataHomeDirectory() + subdir, s.port, s.logger); + ServerP2P s = new ServerP2P(args[1], args[2], args[3]); + ServerManagementUDP smudp = new ServerManagementUDP(s.directories.getDataHomeDirectory() + subdir, s.port, s.logger, s.tracker); + ServerManagementTCP smtcp = new ServerManagementTCP(s.directories.getDataHomeDirectory() + subdir, s.port, s.logger, s.tracker); Thread tudp = new Thread(smudp); tudp.setName("server UDP P2P-JAVA-PROJECT"); tudp.start(); diff --git a/src/tools/HostItem.java b/src/tools/HostItem.java index f2bfbf3..fe15007 100644 --- a/src/tools/HostItem.java +++ b/src/tools/HostItem.java @@ -105,5 +105,24 @@ public class HostItem { public String toString() { return getHostname() + " (port " + getPort() + ")"; } - + + /** Override of equals method + * @param other Object to test equality with + * @return true if equals + */ + public boolean equals(Object other) { + boolean result = false; + if (other instanceof HostItem) { + HostItem that = (HostItem) other; + result = this.getHostname() == that.getHostname() && this.getPort() == that.getPort(); + } + return result; + } + + /** Override of hashCode method + * @return a hash code for this object. + */ + public int hashCode() { + return hostname.hashCode() ^ port; + } } diff --git a/src/tracker/TrackerManagementTCP.java b/src/tracker/TrackerManagementTCP.java index 91d7dab..e8795d9 100644 --- a/src/tracker/TrackerManagementTCP.java +++ b/src/tracker/TrackerManagementTCP.java @@ -101,7 +101,7 @@ public class TrackerManagementTCP implements Runnable { */ private boolean handleRequest() { try { - ProtocolP2PPacketTCP pd = new ProtocolP2PPacketTCP((Object)socket); + ProtocolP2PPacketTCP pd = new ProtocolP2PPacketTCP((Object)s); Payload p = pd.getPayload(); switch (p.getRequestResponseCode()) { case LOAD_REQUEST: @@ -125,9 +125,6 @@ public class TrackerManagementTCP implements Runnable { case DISCOVER_REQUEST: handleDiscover(pd); break; - case LIST_RESPONSE: - handleListResponse(pd); - break; default: logger.writeTCP("Received grabbage from host " + pd.getHostItem(), LogLevel.Action); sendInternalError(pd); @@ -189,8 +186,11 @@ public class TrackerManagementTCP implements Runnable { } // send a list request try { - pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.LIST_REQUEST))); + ProtocolP2PPacket pLReq = (ProtocolP2PPacket) new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.LIST_REQUEST)); + pLReq.sendRequest((Object)host.getTCPSocket()); logger.writeTCP("Received REGISTER. Adding host " + host + " to list. Sending List request", LogLevel.Action); + handleListResponse((ProtocolP2PPacketTCP)pLReq.receiveResponse()); + host.closeTCPSocket(); } catch (Exception e) { // remove from list because list request could not be send hostList.remove(host); diff --git a/src/tracker/TrackerManagementUDP.java b/src/tracker/TrackerManagementUDP.java index f1448f8..c11c54c 100644 --- a/src/tracker/TrackerManagementUDP.java +++ b/src/tracker/TrackerManagementUDP.java @@ -79,9 +79,6 @@ public class TrackerManagementUDP implements Runnable { case DISCOVER_REQUEST: handleDiscover(pd); break; - case LIST_RESPONSE: - handleListResponse(pd); - break; default: logger.writeUDP("Received grabbage from host " + pd.getHostItem(), LogLevel.Action); sendInternalError(pd); @@ -141,8 +138,11 @@ public class TrackerManagementUDP implements Runnable { } // send a list request try { - pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.LIST_REQUEST))); + ProtocolP2PPacket pLReq =(ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.LIST_REQUEST)); + pLReq.sendRequest((Object)host.getUDPSocket()); logger.writeUDP("Received REGISTER. Adding host " + host + " to list. Sending List request", LogLevel.Action); + handleListResponse((ProtocolP2PPacketUDP)pLReq.receiveResponse()); + host.closeUDPSocket(); } catch (Exception e) { // remove from list because list request could not be send hostList.remove(host);