From c5e8a7df3979465d7777c010c10764bd3934d964 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 27 Mar 2020 16:22:42 +0100 Subject: [PATCH] Changes to LoadRequest --- doc/protocol.md | 2 +- src/clientP2P/ClientDownload.java | 12 ++++---- src/clientP2P/ClientDownloadPart.java | 8 +++-- src/clientP2P/ClientDownloadPartTCP.java | 6 ++-- src/clientP2P/ClientDownloadPartUDP.java | 6 ++-- src/clientP2P/ClientDownloadTCP.java | 10 +++---- src/clientP2P/ClientDownloadUDP.java | 10 +++---- src/clientP2P/ClientManagement.java | 5 +++- src/clientP2P/ClientManagementTCP.java | 7 +++-- src/clientP2P/ClientManagementUDP.java | 7 +++-- src/clientP2P/ClientP2P.java | 4 +-- src/protocolP2P/LoadRequest.java | 38 ++++++++++++++++++++---- src/protocolP2P/RequestResponseCode.java | 7 ++++- 13 files changed, 84 insertions(+), 38 deletions(-) diff --git a/doc/protocol.md b/doc/protocol.md index 3bc45b1..997adb0 100644 --- a/doc/protocol.md +++ b/doc/protocol.md @@ -74,7 +74,7 @@ Payload contains 4 bytes: [(bytes 24-27): FILENAME SIZE] (cannot be > to PAYLOAD_SIZE - 20 or be zero) y bytes: [] 2 bytes: port used to register on tracker -? bytes: hostname used to register on tracker followed by \n +? bytes: hostname used to register on tracker ``` Possible responses: Load Response, or Denied diff --git a/src/clientP2P/ClientDownload.java b/src/clientP2P/ClientDownload.java index ed58c3b..c4405c3 100644 --- a/src/clientP2P/ClientDownload.java +++ b/src/clientP2P/ClientDownload.java @@ -57,6 +57,7 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { protected String dirStorage; protected boolean success = false; protected Logger logger; + protected HostItem client; /** Constructor with parameters: filename, list of hosts, parts subdirectory and dirStorage * @param filename name of file to download @@ -64,13 +65,15 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { * @param partsSubdir directory to store .part files * @param dirStorage directory to write assembled file * @param logger Logger + * @param client HostItem of the application */ - public ClientDownload(String filename, List hostList, String partsSubdir, String dirStorage, Logger logger) { + public ClientDownload(String filename, List hostList, String partsSubdir, String dirStorage, Logger logger, HostItem client) { this.partsSubdir = partsSubdir; this.dirStorage = dirStorage; this.filename = filename; this.hostList = hostList; this.logger = logger; + this.client = client; this.stop = false; } @@ -125,16 +128,15 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { } /** Create a clientDownloadPart - * @param filename name of the file to download * @param hostItem Hostitem of the server */ - protected abstract ClientDownloadPart createDownloadPart(String filename, HostItem hostItem); + protected abstract ClientDownloadPart createDownloadPart(HostItem hostItem); /** Starts threads for each server in hostList. */ protected void initThreads() { for(HostItem hostItem: hostList) { - sockList.add(createDownloadPart(filename, hostItem)); + sockList.add(createDownloadPart(hostItem)); } for(ClientDownloadPart c: sockList) { Thread t = new Thread(c); @@ -289,7 +291,7 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { * @throws InternalError */ protected void setSize() throws InternalError { - ProtocolP2PPacket d = createProtocolP2PPacket(new LoadRequest(filename, 0, MAX_PARTIAL_SIZE)); + ProtocolP2PPacket d = createProtocolP2PPacket(new LoadRequest(filename, 0, MAX_PARTIAL_SIZE, client)); try { d.sendRequest(getHostItemSocket(hostList.get(0))); try { diff --git a/src/clientP2P/ClientDownloadPart.java b/src/clientP2P/ClientDownloadPart.java index e12fce3..cccd3ba 100644 --- a/src/clientP2P/ClientDownloadPart.java +++ b/src/clientP2P/ClientDownloadPart.java @@ -26,6 +26,7 @@ import exception.RemoteException; import tools.Logger; import tools.LogLevel; import tools.ServeErrors; +import tools.HostItem; /** Class to download file parts. * @author Louis Royer @@ -46,18 +47,21 @@ public abstract class ClientDownloadPart extends ServeErrors implements Runnable protected static final long MAX_PARTIAL_SIZE = 4096; protected ClientDownload manager; protected Logger logger; + protected HostItem client; /** Constructor with filename, socket, and part subdir * @param filename name of file to download * @param socket socket to use * @param partsSubdir directory to store .part files * @param logger Logger + * @param client HostItem of the application */ - public ClientDownloadPart(ClientDownload manager, String filename, String partsSubdir, Logger logger) { + public ClientDownloadPart(ClientDownload manager, String filename, String partsSubdir, Logger logger, HostItem client) { this.manager = manager; this.partsSubdir = partsSubdir; this.filename = filename; this.logger = logger; + this.client = client; stop = false; failed = false; pendingTasks = new ArrayList<>(); @@ -224,7 +228,7 @@ public abstract class ClientDownloadPart extends ServeErrors implements Runnable } // send request try { - ProtocolP2PPacket d = createProtocolP2PPacket(new LoadRequest(filename, offset.longValue(), MAX_PARTIAL_SIZE)); + ProtocolP2PPacket d = createProtocolP2PPacket(new LoadRequest(filename, offset.longValue(), MAX_PARTIAL_SIZE, client)); d.sendRequest(getSocket()); return d; } catch (InternalError e) { diff --git a/src/clientP2P/ClientDownloadPartTCP.java b/src/clientP2P/ClientDownloadPartTCP.java index 7928735..d354ed4 100644 --- a/src/clientP2P/ClientDownloadPartTCP.java +++ b/src/clientP2P/ClientDownloadPartTCP.java @@ -25,6 +25,7 @@ import remoteException.NotFound; import remoteException.NotATracker; import tools.Logger; import tools.LogLevel; +import tools.HostItem; import clientP2P.ClientDownloadPart; /** Class to download file parts on tcp. @@ -42,9 +43,10 @@ public class ClientDownloadPartTCP extends ClientDownloadPart { * @param socket socket to use * @param partsSubdir directory to store .part files * @param logger Logger + * @param client HostItem of the application */ - public ClientDownloadPartTCP(ClientDownload manager, String filename, Socket socket, String partsSubdir, Logger logger) { - super(manager, filename, partsSubdir, logger); + public ClientDownloadPartTCP(ClientDownload manager, String filename, Socket socket, String partsSubdir, Logger logger, HostItem client) { + super(manager, filename, partsSubdir, logger, client); this.socket = socket; } diff --git a/src/clientP2P/ClientDownloadPartUDP.java b/src/clientP2P/ClientDownloadPartUDP.java index 0387c0c..ae0a24c 100644 --- a/src/clientP2P/ClientDownloadPartUDP.java +++ b/src/clientP2P/ClientDownloadPartUDP.java @@ -24,6 +24,7 @@ import java.io.File; import java.io.IOException; import tools.Logger; import tools.LogLevel; +import tools.HostItem; import clientP2P.ClientDownloadPart; /** Class to download file parts on udp. @@ -42,9 +43,10 @@ public class ClientDownloadPartUDP extends ClientDownloadPart { * @param socket socket to use * @param partsSubdir directory to store .part files * @param logger Logger + * @param client HostItem of the application */ - public ClientDownloadPartUDP(ClientDownload manager, String filename, DatagramSocket socket, String partsSubdir, Logger logger) { - super(manager, filename, partsSubdir, logger); + public ClientDownloadPartUDP(ClientDownload manager, String filename, DatagramSocket socket, String partsSubdir, Logger logger, HostItem client) { + super(manager, filename, partsSubdir, logger, client); this.socket = socket; } diff --git a/src/clientP2P/ClientDownloadTCP.java b/src/clientP2P/ClientDownloadTCP.java index 5d32835..0751845 100644 --- a/src/clientP2P/ClientDownloadTCP.java +++ b/src/clientP2P/ClientDownloadTCP.java @@ -50,17 +50,17 @@ public class ClientDownloadTCP extends ClientDownload { * @param partsSubdir directory to store .part files * @param dirStorage directory to write assembled file * @param logger Logger + * @param client HostItem of the application */ - public ClientDownloadTCP(String filename, List hostList, String partsSubdir, String dirStorage, Logger logger) { - super(filename, hostList, partsSubdir, dirStorage, logger); + public ClientDownloadTCP(String filename, List hostList, String partsSubdir, String dirStorage, Logger logger, HostItem client) { + super(filename, hostList, partsSubdir, dirStorage, logger, client); } /** Create a clientDownloadPart - * @param filename name of the file to download * @param hostItem Hostitem of the server */ - protected ClientDownloadPart createDownloadPart(String filename, HostItem hostItem) { - return (ClientDownloadPart)new ClientDownloadPartTCP((ClientDownload)this, filename, hostItem.getTCPSocket(), partsSubdir, logger); + protected ClientDownloadPart createDownloadPart(HostItem hostItem) { + return (ClientDownloadPart)new ClientDownloadPartTCP((ClientDownload)this, filename, hostItem.getTCPSocket(), partsSubdir, logger, client); } /** Close HostItem socket diff --git a/src/clientP2P/ClientDownloadUDP.java b/src/clientP2P/ClientDownloadUDP.java index 008caaf..5d5dd2a 100644 --- a/src/clientP2P/ClientDownloadUDP.java +++ b/src/clientP2P/ClientDownloadUDP.java @@ -50,17 +50,17 @@ public class ClientDownloadUDP extends ClientDownload { * @param partsSubdir directory to store .part files * @param dirStorage directory to write assembled file * @param logger Logger + * @param client HostItem of the application */ - public ClientDownloadUDP(String filename, List hostList, String partsSubdir, String dirStorage, Logger logger) { - super(filename, hostList, partsSubdir, dirStorage, logger); + public ClientDownloadUDP(String filename, List hostList, String partsSubdir, String dirStorage, Logger logger, HostItem client) { + super(filename, hostList, partsSubdir, dirStorage, logger, client); } /** Create a clientDownloadPart - * @param filename name of the file to download * @param hostItem Hostitem of the server */ - protected ClientDownloadPart createDownloadPart(String filename, HostItem hostItem) { - return (ClientDownloadPart)new ClientDownloadPartUDP((ClientDownload)this, filename, hostItem.getUDPSocket(), partsSubdir, logger); + protected ClientDownloadPart createDownloadPart(HostItem hostItem) { + return (ClientDownloadPart)new ClientDownloadPartUDP((ClientDownload)this, filename, hostItem.getUDPSocket(), partsSubdir, logger, client); } /** Implementation of writeLog diff --git a/src/clientP2P/ClientManagement.java b/src/clientP2P/ClientManagement.java index cf1dad8..a5a481e 100644 --- a/src/clientP2P/ClientManagement.java +++ b/src/clientP2P/ClientManagement.java @@ -46,6 +46,7 @@ public abstract class ClientManagement extends ServeErrors implements Runnable { protected String partsSubdir; protected List hostList; protected HostItem tracker; + protected HostItem client; protected Logger logger; protected Scanner scanner; protected ClientDownload downLoader; @@ -56,13 +57,15 @@ public abstract class ClientManagement extends ServeErrors implements Runnable { * @param partsSubdir subdirectory to store file parts * @param logger Loggger * @param scanner Scanner used to read input + * @param client HostItem of the application */ - public ClientManagement(String baseDirectory, HostItem tracker, String partsSubdir, Logger logger, Scanner scanner) { + public ClientManagement(String baseDirectory, HostItem tracker, String partsSubdir, Logger logger, Scanner scanner, HostItem client) { this.scanner = scanner; this.baseDirectory = baseDirectory; this.tracker = tracker; this.partsSubdir = partsSubdir; this.logger = logger; + this.client = client; try { initHostList(); } catch (InternalError e) { diff --git a/src/clientP2P/ClientManagementTCP.java b/src/clientP2P/ClientManagementTCP.java index 559fd71..e922157 100644 --- a/src/clientP2P/ClientManagementTCP.java +++ b/src/clientP2P/ClientManagementTCP.java @@ -24,16 +24,17 @@ public class ClientManagementTCP extends ClientManagement { * @param partsSubdir subdirectory to store file parts * @param logger Loggger * @param scanner Scanner used to read input + * @param client HostItem of the application */ - public ClientManagementTCP(String baseDirectory, HostItem tracker, String partsSubdir, Logger logger, Scanner scanner) { - super(baseDirectory, tracker, partsSubdir, logger, scanner); + public ClientManagementTCP(String baseDirectory, HostItem tracker, String partsSubdir, Logger logger, Scanner scanner, HostItem client) { + super(baseDirectory, tracker, partsSubdir, logger, scanner, client); } /** Initialize downloader * @param filename Name of the file to download */ protected void initDownloader(String filename) { - downLoader = (ClientDownload) new ClientDownloadTCP(filename, hostList, partsSubdir, baseDirectory, logger); + downLoader = (ClientDownload) new ClientDownloadTCP(filename, hostList, partsSubdir, baseDirectory, logger, client); } diff --git a/src/clientP2P/ClientManagementUDP.java b/src/clientP2P/ClientManagementUDP.java index 19e7a0b..e34db9c 100644 --- a/src/clientP2P/ClientManagementUDP.java +++ b/src/clientP2P/ClientManagementUDP.java @@ -23,16 +23,17 @@ public class ClientManagementUDP extends ClientManagement { * @param partsSubdir subdirectory to store file parts * @param logger Loggger * @param scanner Scanner used to read input + * @param client HostItem of the application */ - public ClientManagementUDP(String baseDirectory, HostItem tracker, String partsSubdir, Logger logger, Scanner scanner) { - super(baseDirectory, tracker, partsSubdir, logger, scanner); + public ClientManagementUDP(String baseDirectory, HostItem tracker, String partsSubdir, Logger logger, Scanner scanner, HostItem client) { + super(baseDirectory, tracker, partsSubdir, logger, scanner, client); } /** Initialize downloader * @param filename Name of the file to download */ protected void initDownloader(String filename) { - downLoader = (ClientDownload) new ClientDownloadUDP(filename, hostList, partsSubdir, baseDirectory, logger); + downLoader = (ClientDownload) new ClientDownloadUDP(filename, hostList, partsSubdir, baseDirectory, logger, client); } /** Implementation of writeLog diff --git a/src/clientP2P/ClientP2P.java b/src/clientP2P/ClientP2P.java index 5985479..15c8acc 100644 --- a/src/clientP2P/ClientP2P.java +++ b/src/clientP2P/ClientP2P.java @@ -178,7 +178,7 @@ public class ClientP2P { case "upd": // to avoid users typos case "2" : System.out.println("Starting with UDP"); - ClientManagementUDP cmudp = new ClientManagementUDP(c.directories.getDataHomeDirectory(), c.tracker, c.directories.getDataHomeDirectory() + c.partsDir, c.loggerClient, c.scanner); + ClientManagementUDP cmudp = new ClientManagementUDP(c.directories.getDataHomeDirectory(), c.tracker, c.directories.getDataHomeDirectory() + c.partsDir, c.loggerClient, c.scanner, c.server); tclient = new Thread(cmudp); break; case "TCP": @@ -186,7 +186,7 @@ public class ClientP2P { case "1": default: System.out.println("Starting with TCP"); - ClientManagementTCP cmtcp = new ClientManagementTCP(c.directories.getDataHomeDirectory(), c.tracker, c.directories.getDataHomeDirectory() + c.partsDir, c.loggerClient, c.scanner); + ClientManagementTCP cmtcp = new ClientManagementTCP(c.directories.getDataHomeDirectory(), c.tracker, c.directories.getDataHomeDirectory() + c.partsDir, c.loggerClient, c.scanner, c.server); tclient = new Thread(cmtcp); break; } diff --git a/src/protocolP2P/LoadRequest.java b/src/protocolP2P/LoadRequest.java index 86f0b75..b6622a0 100644 --- a/src/protocolP2P/LoadRequest.java +++ b/src/protocolP2P/LoadRequest.java @@ -6,6 +6,7 @@ import localException.ProtocolError; import localException.InternalError; import localException.SizeError; import tools.BytesArrayTools; +import tools.HostItem; /** Representation of payload for load request. * @author Louis Royer @@ -17,18 +18,20 @@ public class LoadRequest extends Payload { private String filename; private long maxSizePartialContent; private long offset; + private HostItem hostItem; static final private int OFFSET_POSITION = PAYLOAD_START_POSITION; static final private int MAX_SIZE_PARTIAL_CONTENT_POSITION = OFFSET_POSITION + 8; static final private int FILENAME_SIZE_POSITION = MAX_SIZE_PARTIAL_CONTENT_POSITION + 8; static final private int FILENAME_POSITION = FILENAME_SIZE_POSITION + 4; - /** Constructor (typically used by the server) with a filename parameter. + /** Constructor (typically used by the client) with a filename parameter. * @param filename name of the file to download. Must not be empty. * @param offset offset of the bloc * @param maxSizePartialContent partial content in response should not excess this size, but this can be less (by example if endoffile is reached or server doesn't have the full block requested) + * @param hostItem hostItem used by the client to register on the tracker * @throws InternalError */ - public LoadRequest(String filename, long offset, long maxSizePartialContent) throws InternalError { + public LoadRequest(String filename, long offset, long maxSizePartialContent, HostItem hostItem) throws InternalError { super(RequestResponseCode.LOAD_REQUEST); /* assert to help debugging */ assert filename.length() != 0 : "Payload size of LoadRequest must not be empty"; @@ -38,9 +41,10 @@ public class LoadRequest extends Payload { this.filename = filename; this.maxSizePartialContent = maxSizePartialContent; this.offset = offset; + this.hostItem = hostItem; } - /** Constructor (typically used by client) with a byte[] parameter containing the Packet received. + /** Constructor (typically used by server) with a byte[] parameter containing the Packet received. * @param packet the full Packet received * @throws SizeError * @throws InternalError @@ -64,6 +68,12 @@ public class LoadRequest extends Payload { /* Read filename */ int size = BytesArrayTools.readInt(packet, FILENAME_SIZE_POSITION); filename = BytesArrayTools.readString(packet, FILENAME_POSITION, size); + + /* Read hostItem */ + int portPosition = FILENAME_POSITION + size; + int hostnameStartPosition = portPosition + 2; + int hostnameSize = getPayloadSize(packet) - hostnameStartPosition; + hostItem = new HostItem(BytesArrayTools.readString(packet, hostnameStartPosition, hostnameSize), BytesArrayTools.readInt16Bits(packet, portPosition)); } /** Returns a byte[] containing Packet with padding. @@ -75,8 +85,9 @@ public class LoadRequest extends Payload { protected byte[] toPacket() throws InternalError { // compute size int filenameSize = filename.length(); - int size = FILENAME_POSITION + filenameSize; - byte[] packet = new byte[size + 1]; // java initialize all to zero + String hostname = hostItem.getHostname(); + int size = 1 + FILENAME_POSITION + filenameSize + 2 + hostname.length(); + byte[] packet = new byte[size]; // java initialize all to zero // set request/response code packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; // set Payload size @@ -89,7 +100,15 @@ public class LoadRequest extends Payload { BytesArrayTools.write(packet, FILENAME_SIZE_POSITION, filenameSize); // Write filename BytesArrayTools.write(packet, filename, FILENAME_POSITION); - return packet; + // Write hostitem + int portPosition = FILENAME_POSITION + filenameSize; + try { + BytesArrayTools.write16Bits(packet, portPosition, hostItem.getPort()); + BytesArrayTools.write(packet, hostname, portPosition + 2); + return packet; + } catch (SizeError e) { + throw new InternalError(); + } } /** filename getter. @@ -112,4 +131,11 @@ public class LoadRequest extends Payload { public long getMaxSizePartialContent() { return maxSizePartialContent; } + + /** hostItem getter. + * @return hostItem + */ + public HostItem getHostItem() { + return hostItem; + } } diff --git a/src/protocolP2P/RequestResponseCode.java b/src/protocolP2P/RequestResponseCode.java index f216d8c..b2994f4 100644 --- a/src/protocolP2P/RequestResponseCode.java +++ b/src/protocolP2P/RequestResponseCode.java @@ -18,17 +18,22 @@ public enum RequestResponseCode { DISCOVER_REQUEST(CodeType.REQUEST_TRACKER, (byte)0x03), REGISTER(CodeType.REQUEST_TRACKER, (byte)0x04), UNREGISTER(CodeType.REQUEST_TRACKER, (byte)0x05), + RATIO_REQUEST(CodeType.REQUEST_TRACKER, (byte)0x06), + UPDATE_RATIO(CodeType.REQUEST_TRACKER, (byte)0x07), LIST_RESPONSE(CodeType.RESPONSE, (byte)0x80), LOAD_RESPONSE(CodeType.RESPONSE, (byte)0x81), HASH_RESPONSE(CodeType.RESPONSE, (byte)0x82), DISCOVER_RESPONSE(CodeType.RESPONSE, (byte)0x83), + RATIO_RESPONSE(CodeType.RESPONSE, (byte)0x86), VERSION_ERROR(CodeType.ERROR, (byte)0xC0), PROTOCOL_ERROR(CodeType.ERROR, (byte)0xC1), INTERNAL_ERROR(CodeType.ERROR, (byte)0xC2), EMPTY_DIRECTORY(CodeType.ERROR, (byte)0xC3), NOT_FOUND(CodeType.ERROR, (byte)0xC4), EMPTY_FILE(CodeType.ERROR, (byte)0xC5), - NOT_A_TRACKER(CodeType.ERROR, (byte)0xC6); + NOT_A_TRACKER(CodeType.ERROR, (byte)0xC6), + UNKNOWN_HOST(CodeType.ERROR, (byte)0xC7), + DENIED(CodeType.ERROR, (byte)0xC8); public final CodeType codeType; public final byte codeValue;