diff --git a/src/clientP2P/ClientDownload.java b/src/clientP2P/ClientDownload.java index 0a3b18d..f1b44f9 100644 --- a/src/clientP2P/ClientDownload.java +++ b/src/clientP2P/ClientDownload.java @@ -126,8 +126,7 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { try { sockList.get(rand.nextInt(sockList.size())).assignTask(offset); offsetsPending.add(offset); - System.err.println("Assigned task "+ offset); - writeLog("Assigned task "+ offset, LogLevel.Info); + writeLog("Assigned task: #"+ offset, LogLevel.Info); } catch(InterruptedException e) { writeLog(e, LogLevel.Error); throw new InternalError(); @@ -232,7 +231,6 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { writeLog(e, LogLevel.Error); hash = new byte[0]; } catch (NotFound e) { - writeLog(e, LogLevel.Error); hash = new byte[0]; } catch (LocalException e) { writeLog(e, LogLevel.Error); @@ -258,6 +256,7 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { */ protected void purgeList() throws InternalError { List blackList = new ArrayList(); + writeLog("Potential peers (before purge): " + hostList.size(), LogLevel.Debug); boolean first = false; byte[] hashsum; for(HostItem host: hostList) { @@ -276,6 +275,7 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { for(HostItem host: blackList) { hostList.remove(host); } + writeLog("Peers (after purge): " + hostList.size(), LogLevel.Debug); writeLog("Host list purge: done", LogLevel.Info); } @@ -368,17 +368,11 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { public void run() { try { init(); - if (stop) { - writeLog("File is smaller than part max size.", LogLevel.Info); - closeHostItemSocket(hostList.get(0)); - } else { - writeLog("File is bigger than part max size.", LogLevel.Info); - purgeList(); - initThreads(); - while(!stop) { - assignTasks(); - checkTasksStatus(); - } + purgeList(); + initThreads(); + while(!stop) { + assignTasks(); + checkTasksStatus(); } writeLog("Reassembling file parts.", LogLevel.Info); reassembleFile(); diff --git a/src/clientP2P/ClientDownloadPart.java b/src/clientP2P/ClientDownloadPart.java index c66fbfe..e9cd602 100644 --- a/src/clientP2P/ClientDownloadPart.java +++ b/src/clientP2P/ClientDownloadPart.java @@ -8,6 +8,7 @@ import protocolP2P.ProtocolP2PPacket; import protocolP2P.Payload; import protocolP2P.LoadRequest; import protocolP2P.FilePart; +import protocolP2P.Denied; import localException.InternalError; import localException.ProtocolError; import localException.TransmissionError; @@ -203,7 +204,6 @@ public abstract class ClientDownloadPart extends ServeErrors implements Runnable if (p == null) { stop = true; } - failed = downloadPart(p); if (failed) { System.err.println("Error: DownloadPart failed."); @@ -224,7 +224,7 @@ public abstract class ClientDownloadPart extends ServeErrors implements Runnable * @return ProtocolP2PPacketTCP used to send request */ protected ProtocolP2PPacket reqPart(Long offset) { - writeLog("New request: " + offset, LogLevel.Info); + writeLog("New request: #" + offset, LogLevel.Info); // maintain tracking of tasks if (toDoTasks.contains(offset)) { try { @@ -279,6 +279,22 @@ public abstract class ClientDownloadPart extends ServeErrors implements Runnable } try { Payload p = d.receiveResponse().getPayload(); + if (p instanceof Denied) { + Denied denied = (Denied)p; + if (!denied.getFilename().equals(filename)) { + writeLog("wrong file deny response received: `" + denied.getFilename() + "`", LogLevel.Error); + return true; + } + Long offset = Long.valueOf(denied.getOffset()); + if (pendingTasks.contains(offset)) { + pendingTasks.remove(offset); + toDoTasks.add(offset); + return false; + } else { + writeLog("wrong file offset deny received: " + offset, LogLevel.Error); + return true; + } + } assert p instanceof FilePart : "This payload must be instance of FilePart"; if (!(p instanceof FilePart)) { writeLog("cannot get size.", LogLevel.Error); diff --git a/src/clientP2P/ClientManagement.java b/src/clientP2P/ClientManagement.java index 2750c4f..97f07d2 100644 --- a/src/clientP2P/ClientManagement.java +++ b/src/clientP2P/ClientManagement.java @@ -26,6 +26,7 @@ import remoteException.NotFound; import remoteException.ProtocolRemoteError; import remoteException.VersionRemoteError; import remoteException.NotATracker; +import remoteException.UnknownHost; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -165,6 +166,9 @@ public abstract class ClientManagement extends ServeErrors implements Runnable { } catch (NotATracker e) { writeLog(e, LogLevel.Error); throw new ProtocolError(); + } catch (UnknownHost e) { + writeLog(e, LogLevel.Error); + throw new ProtocolError(); } } @@ -212,6 +216,7 @@ public abstract class ClientManagement extends ServeErrors implements Runnable { throw new InternalError(); } else { downLoader.sendRatioUpdate(); + writeLog("Ratio updates sent.", LogLevel.Info); } } else { throw new InternalError(); diff --git a/src/protocolP2P/DiscoverResponse.java b/src/protocolP2P/DiscoverResponse.java index 97a9cd4..6fa7bb5 100644 --- a/src/protocolP2P/DiscoverResponse.java +++ b/src/protocolP2P/DiscoverResponse.java @@ -56,7 +56,7 @@ public class DiscoverResponse extends Payload { int port = BytesArrayTools.readInt16Bits(packet, i); i += 2; String hostname = BytesArrayTools.readString(packet, i, "\n"); - i += hostname.length(); + i += hostname.length() + 1; // 1 for the "\n" hostList.add(new HostItem(hostname, port)); } } diff --git a/src/protocolP2P/LoadRequest.java b/src/protocolP2P/LoadRequest.java index a662f62..2834f9b 100644 --- a/src/protocolP2P/LoadRequest.java +++ b/src/protocolP2P/LoadRequest.java @@ -72,7 +72,7 @@ public class LoadRequest extends Payload { /* Read hostItem */ int portPosition = FILENAME_POSITION + size; int hostnameStartPosition = portPosition + 2; - int hostnameSize = getPayloadSize(packet) - hostnameStartPosition; + int hostnameSize = getPayloadSize(packet) - hostnameStartPosition + PAYLOAD_START_POSITION; hostItem = new HostItem(BytesArrayTools.readString(packet, hostnameStartPosition, hostnameSize), BytesArrayTools.readInt16Bits(packet, portPosition)); } diff --git a/src/protocolP2P/ProtocolP2PPacket.java b/src/protocolP2P/ProtocolP2PPacket.java index db9c4b4..dd1cb79 100644 --- a/src/protocolP2P/ProtocolP2PPacket.java +++ b/src/protocolP2P/ProtocolP2PPacket.java @@ -12,6 +12,7 @@ import remoteException.ProtocolRemoteError; import remoteException.VersionRemoteError; import remoteException.EmptyFile; import remoteException.NotATracker; +import remoteException.UnknownHost; import java.io.IOException; import tools.HostItem; @@ -72,8 +73,9 @@ public abstract class ProtocolP2PPacket < T extends Payload>{ * @throws SizeError * @throws IOException * @throws SocketClosed + * @throws UnknownHost */ - public abstract ProtocolP2PPacket receiveResponse() throws EmptyFile, NotFound, NotATracker, EmptyDirectory, InternalRemoteError, VersionRemoteError, ProtocolRemoteError, TransmissionError, ProtocolError, VersionError, InternalError, SizeError, IOException, SocketClosed; + public abstract ProtocolP2PPacket receiveResponse() throws EmptyFile, NotFound, NotATracker, EmptyDirectory, InternalRemoteError, VersionRemoteError, ProtocolRemoteError, TransmissionError, ProtocolError, VersionError, InternalError, SizeError, IOException, SocketClosed, UnknownHost; /** Receive a request, subclasses must overwrite this constructor. * @param socket socket used to get the request diff --git a/src/protocolP2P/ProtocolP2PPacketTCP.java b/src/protocolP2P/ProtocolP2PPacketTCP.java index 52da813..69c8e6e 100644 --- a/src/protocolP2P/ProtocolP2PPacketTCP.java +++ b/src/protocolP2P/ProtocolP2PPacketTCP.java @@ -12,6 +12,7 @@ import remoteException.NotFound; import remoteException.ProtocolRemoteError; import remoteException.VersionRemoteError; import remoteException.EmptyFile; +import remoteException.UnknownHost; import tools.HostItem; import protocolP2P.Payload; import protocolP2P.RequestResponseCode; @@ -212,8 +213,9 @@ public class ProtocolP2PPacketTCP < T extends Payload > extends ProtocolP2PPacke * @throws SizeError * @throws IOException * @throws SocketClosed + * @throws UnknownHost */ - public ProtocolP2PPacket receiveResponse() throws EmptyFile, NotFound, NotATracker, EmptyDirectory, InternalRemoteError, VersionRemoteError, ProtocolRemoteError, TransmissionError, ProtocolError, VersionError, InternalError, SizeError, IOException, SocketClosed { + public ProtocolP2PPacket receiveResponse() throws EmptyFile, NotFound, NotATracker, EmptyDirectory, InternalRemoteError, VersionRemoteError, ProtocolRemoteError, TransmissionError, ProtocolError, VersionError, InternalError, SizeError, IOException, SocketClosed, UnknownHost { assert requestSocket != null : "Cannot receive response because request packet not sent."; if (requestSocket == null) { throw new InternalError(); @@ -253,6 +255,8 @@ public class ProtocolP2PPacketTCP < T extends Payload > extends ProtocolP2PPacke throw new EmptyFile(); case NOT_A_TRACKER: throw new NotATracker(); + case UNKNOWN_HOST: + throw new UnknownHost(); default : return (ProtocolP2PPacket)p; } diff --git a/src/protocolP2P/ProtocolP2PPacketUDP.java b/src/protocolP2P/ProtocolP2PPacketUDP.java index 5073d0e..0b639fe 100644 --- a/src/protocolP2P/ProtocolP2PPacketUDP.java +++ b/src/protocolP2P/ProtocolP2PPacketUDP.java @@ -12,6 +12,7 @@ import remoteException.NotFound; import remoteException.ProtocolRemoteError; import remoteException.VersionRemoteError; import remoteException.EmptyFile; +import remoteException.UnknownHost; import tools.BytesArrayTools; import tools.HostItem; import protocolP2P.Payload; @@ -207,8 +208,9 @@ public class ProtocolP2PPacketUDP < T extends Payload> extends ProtocolP2PPacket * @throws InternalError * @throws SizeError * @throws IOException + * @throws UnknownHost */ - public ProtocolP2PPacket receiveResponse() throws EmptyFile, NotFound, NotATracker, EmptyDirectory, InternalRemoteError, VersionRemoteError, ProtocolRemoteError, TransmissionError, ProtocolError, VersionError, InternalError, SizeError, IOException { + public ProtocolP2PPacket receiveResponse() throws EmptyFile, NotFound, NotATracker, EmptyDirectory, InternalRemoteError, VersionRemoteError, ProtocolRemoteError, TransmissionError, ProtocolError, VersionError, InternalError, SizeError, IOException, UnknownHost { assert requestSocket != null : "Cannot receive response because request packet not sent."; if (requestSocket == null) { throw new InternalError(); @@ -237,6 +239,8 @@ public class ProtocolP2PPacketUDP < T extends Payload> extends ProtocolP2PPacket throw new EmptyFile(); case NOT_A_TRACKER: throw new NotATracker(); + case UNKNOWN_HOST: + throw new UnknownHost(); default : return (ProtocolP2PPacket)p; } diff --git a/src/serverP2P/RatioWatcher.java b/src/serverP2P/RatioWatcher.java new file mode 100644 index 0000000..884c818 --- /dev/null +++ b/src/serverP2P/RatioWatcher.java @@ -0,0 +1,177 @@ +package serverP2P; +import tools.Logger; +import tools.LogLevel; +import tools.HostItem; +import java.util.Map; +import java.util.HashMap; +import java.io.IOException; +import exception.RemoteException; +import exception.LocalException; +import protocolP2P.RatioRequest; +import protocolP2P.RatioResponse; +import protocolP2P.Payload; +import protocolP2P.ProtocolP2PPacket; +import remoteException.UnknownHost; +import remoteException.NotATracker; +import localException.InternalError; + +/** Class allowing to keep the tracker informed about ratios + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ +public abstract class RatioWatcher implements Runnable { + final static double punishmentFactor = 1.2; + protected Logger logger; + protected volatile boolean stop; + protected long time; + protected boolean force; + protected HostItem tracker; + protected Thread thread; + protected Map cachePunishmentProbability = new HashMap<>(); + protected boolean lock; + + + /** Constructor + * @param logger Logger + * @param millis Time interval before recheck + * @param tracker HostItem for the tracker + */ + public RatioWatcher(Logger logger, long millis, HostItem tracker) { + assert logger != null : "Logger is null"; + assert tracker != null : "Tracker is null"; + this.logger = logger; + time = millis; + this.tracker = tracker; + lock = false; + } + + + /** Runnable implementation */ + public void run() { + writeLog("Ratio watcher started : delay " + time + " milliseconds.", LogLevel.Info); + while(!stop) { + try { + clean(); + Thread.sleep(time); + } catch(InterruptedException e) { + writeLog("Ratio watcher interrupted", LogLevel.Info); + setStop(); + } + } + } + + /** Invalidate the cache by cleaning all hashmaps + * @throws InterruptedException + */ + protected synchronized void clean() throws InterruptedException{ + while(lock) { + this.wait(); + } + lock = true; + cachePunishmentProbability.clear(); + lock = false; + this.notifyAll(); + } + + + /** Get Up-ratio for an applications + * @param application HostItem of the application + * @return Punishment Probability + * @throws UnknownHost + */ + protected synchronized double getPunishmentProbability(HostItem application) throws InternalError, UnknownHost { + try { + while(lock) { + this.wait(); + } + lock = true; + if (!cachePunishmentProbability.containsKey(application)) { + // update if not in cache + try { + ProtocolP2PPacket p = createProtocolP2PPacket(new RatioRequest(application)); + p.sendRequest(getTrackerSocket()); + Payload resp = p.receiveResponse().getPayload(); + if (!(resp instanceof RatioResponse)) { + throw new InternalError(); + } + RatioResponse rresp = (RatioResponse)resp; + if (!rresp.getHostItem().equals(application)) { + writeLog("Ratio response host is not the expected one. Expected : " + + application + ". Received : " + rresp.getHostItem(), LogLevel.Debug); + throw new InternalError(); + } + long up = rresp.getTotalUp(); + long down = rresp.getTotalDown(); + assert punishmentFactor > 1 : "The punishment factor must be greater than 1"; + if (down == 0 || (punishmentFactor * up) >= down) { + cachePunishmentProbability.put(application, Double.valueOf(0)); + } else { + cachePunishmentProbability.put(application, Double.valueOf((down - up)/(down * punishmentFactor))); + } + } catch (UnknownHost e) { + throw e; + } catch (IOException e) { + throw new InternalError(); + } catch (LocalException e) { + writeLog(e, LogLevel.Error); + throw new InternalError(); + } catch (RemoteException e) { + writeLog(e, LogLevel.Error); + throw new InternalError(); + } + } + double ret = cachePunishmentProbability.get(application); + lock = false; + this.notifyAll(); + return ret; + } catch (InterruptedException e) { + throw new InternalError(); + } + } + + /** Ask the thread to stop + */ + public void setStop() { + stop = true; + if (thread != null) { + thread.interrupt(); + } + } + + /** Implementation of writeLog + * @param text Text to log + * @param logLevel level of logging + */ + protected abstract void writeLog(String text, LogLevel logLevel); + + /** Implementation of writeLog + * @param e exception to log + * @param logLevel level of logging + */ + protected abstract void writeLog(Exception e, LogLevel logLevel); + + /** Set thread + * @param thread Thread + */ + public void setThread(Thread thread) { + this.thread = thread; + } + + /** Create packets + * @param payload Payload + */ + protected abstract < T extends Payload > ProtocolP2PPacket createProtocolP2PPacket(T payload); + + /** Tracker socket getter + * @return tracker socket + */ + protected abstract Object getTrackerSocket(); + + /** Closes tracker socket + */ + protected abstract void closeTrackerSocket(); + + +} diff --git a/src/serverP2P/RatioWatcherTCP.java b/src/serverP2P/RatioWatcherTCP.java new file mode 100644 index 0000000..5184ce4 --- /dev/null +++ b/src/serverP2P/RatioWatcherTCP.java @@ -0,0 +1,66 @@ +package serverP2P; +import tools.Logger; +import tools.LogLevel; +import protocolP2P.ProtocolP2PPacket; +import protocolP2P.ProtocolP2PPacketTCP; +import protocolP2P.Payload; +import tools.HostItem; +import serverP2P.RatioWatcher; + +/** Class allowing to keep the tracker informed about file list (TCP impl.) + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ +public class RatioWatcherTCP extends RatioWatcher { + + /** Constructor + * @param logger Logger + * @param millis Time interval before recheck + * @param tracker HostItem for the tracker + */ + public RatioWatcherTCP(Logger logger, long millis, HostItem tracker) { + super(logger, millis, tracker); + assert logger != null : "Logger is null"; + assert tracker != null : "Tracker is null"; + } + + /** Implementation of writeLog + * @param text Text to log + * @param logLevel level of logging + */ + protected void writeLog(String text, LogLevel logLevel) { + logger.writeTCP(text, logLevel); + } + + /** Implementation of writeLog + * @param e exception to log + * @param logLevel level of logging + */ + protected void writeLog(Exception e, LogLevel logLevel) { + logger.writeTCP(e, logLevel); + } + + /** Create packets + * @param payload Payload + */ + protected < T extends Payload > ProtocolP2PPacket createProtocolP2PPacket(T payload) { + return (ProtocolP2PPacket)new ProtocolP2PPacketTCP(payload); + } + + /** Tracker socket getter + * @return tracker socket + */ + protected Object getTrackerSocket() { + return tracker.getTCPSocket(); + } + + /** Closes tracker socket + */ + protected void closeTrackerSocket() { + tracker.closeTCPSocket(); + } + + +} diff --git a/src/serverP2P/RatioWatcherUDP.java b/src/serverP2P/RatioWatcherUDP.java new file mode 100644 index 0000000..dca0789 --- /dev/null +++ b/src/serverP2P/RatioWatcherUDP.java @@ -0,0 +1,64 @@ +package serverP2P; +import tools.Logger; +import tools.LogLevel; +import protocolP2P.ProtocolP2PPacket; +import protocolP2P.ProtocolP2PPacketUDP; +import protocolP2P.Payload; +import tools.HostItem; +import serverP2P.RatioWatcher; + +/** Class allowing to keep the tracker informed about file list (UDP impl.) + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ +public class RatioWatcherUDP extends RatioWatcher { + + /** Constructor + * @param logger Logger + * @param millis Time interval before recheck + * @param tracker HostItem for the tracker + */ + public RatioWatcherUDP(Logger logger, long millis, HostItem tracker) { + super(logger, millis, tracker); + assert logger != null : "Logger is null"; + assert tracker != null : "Tracker is null"; + } + + /** Implementation of writeLog + * @param text Text to log + * @param logLevel level of logging + */ + protected void writeLog(String text, LogLevel logLevel) { + logger.writeUDP(text, logLevel); + } + + /** Implementation of writeLog + * @param e exception to log + * @param logLevel level of logging + */ + protected void writeLog(Exception e, LogLevel logLevel) { + logger.writeUDP(e, logLevel); + } + + /** Create packets + * @param payload Payload + */ + protected < T extends Payload > ProtocolP2PPacket createProtocolP2PPacket(T payload) { + return (ProtocolP2PPacket)new ProtocolP2PPacketUDP(payload); + } + + /** Tracker socket getter + * @return tracker socket + */ + protected Object getTrackerSocket() { + return tracker.getUDPSocket(); + } + + /** Closes tracker socket + */ + protected void closeTrackerSocket() { + tracker.closeUDPSocket(); + } +} diff --git a/src/serverP2P/ServerManagement.java b/src/serverP2P/ServerManagement.java index 702b550..af7ed6f 100644 --- a/src/serverP2P/ServerManagement.java +++ b/src/serverP2P/ServerManagement.java @@ -1,5 +1,6 @@ package serverP2P; import serverP2P.FileWatcher; +import serverP2P.RatioWatcher; import tools.Logger; import tools.LogLevel; import tools.HostItem; @@ -16,14 +17,18 @@ import protocolP2P.HashAlgorithm; import protocolP2P.Unregister; import protocolP2P.SizeRequest; import protocolP2P.SizeResponse; +import protocolP2P.Denied; import java.nio.file.Paths; import java.nio.file.Files; import java.io.File; import java.util.Arrays; import java.util.Map; import java.util.HashMap; +import java.util.Random; import java.io.IOException; import exception.LocalException; +import localException.InternalError; +import remoteException.UnknownHost; /** Implementation of P2P-JAVA-PROJECT VERSION 1.0 protocol. * @author Louis Royer @@ -39,6 +44,8 @@ public abstract class ServerManagement extends ServeErrors implements Runnable { protected String baseDirectory; protected HostItem server; protected HostItem tracker; + protected Random punisher = new Random(); + protected RatioWatcher ratioWatcher; /** Constructor */ public ServerManagement(String baseDirectory, HostItem server, HostItem tracker, Logger logger) { @@ -58,6 +65,7 @@ public abstract class ServerManagement extends ServeErrors implements Runnable { public void setStop() { stop = true; fileListWatcher.setStop(); + ratioWatcher.setStop(); sendUnregisterRequest(); closeSocket(); } @@ -145,27 +153,48 @@ public abstract class ServerManagement extends ServeErrors implements Runnable { long offset = ((LoadRequest)p).getOffset(); long maxSizePartialContent = ((LoadRequest)p).getMaxSizePartialContent(); try { - byte[] fullLoad = Files.readAllBytes(Paths.get(baseDirectory + filename)); - long sizeToSend = 0; - if (fullLoad.length - offset < maxSizePartialContent) { - writeLog("Sending last partialContent", LogLevel.Debug); - sizeToSend = fullLoad.length - offset; - } else { - sizeToSend = maxSizePartialContent; - } - writeLog("maxSizePartialContent: " + maxSizePartialContent, LogLevel.Debug); - writeLog("Sending " + filename + " from " + offset + " to " + (offset + sizeToSend), LogLevel.Debug); - byte[] load = Arrays.copyOfRange(fullLoad, (int)offset, (int)(offset + sizeToSend)); String[] fileList = fileListWatcher.getFileList(); if (Arrays.binarySearch(fileList, filename) >= 0) { try { - if (load.length == 0) { - sendEmptyFile(pd); + double proba = ratioWatcher.getPunishmentProbability(((LoadRequest)p).getHostItem()); + if (punisher.nextDouble() <= proba) { + writeLog("Sending punishment", LogLevel.Debug); + pd.sendResponse(createProtocolP2PPacket(new Denied(filename, offset))); } else { - pd.sendResponse(createProtocolP2PPacket((Payload)(new FilePart(filename, offset, load)))); + byte[] fullLoad = Files.readAllBytes(Paths.get(baseDirectory + filename)); + long sizeToSend = 0; + if (fullLoad.length - offset < maxSizePartialContent) { + writeLog("Sending last partialContent", LogLevel.Debug); + sizeToSend = fullLoad.length - offset; + } else { + sizeToSend = maxSizePartialContent; + } + writeLog("maxSizePartialContent: " + maxSizePartialContent, LogLevel.Debug); + writeLog("Sending " + filename + " from " + offset + " to " + (offset + sizeToSend), LogLevel.Debug); + byte[] load = Arrays.copyOfRange(fullLoad, (int)offset, (int)(offset + sizeToSend)); + try { + if (load.length == 0) { + sendEmptyFile(pd); + } else { + pd.sendResponse(createProtocolP2PPacket((Payload)(new FilePart(filename, offset, load)))); + } + } catch (Exception e2) { + writeLog(e2, LogLevel.Error); + } } - } catch (Exception e2) { - writeLog(e2, LogLevel.Error); + } catch (InternalError e) { + writeLog("InternalError", LogLevel.Debug); + writeLog(e, LogLevel.Debug); + sendInternalError(pd); + return; + } catch (UnknownHost e) { + writeLog("Unknown host: " + ((LoadRequest)p).getHostItem(), LogLevel.Debug); + writeLog(e, LogLevel.Debug); + sendInternalError(pd); + return; + } catch(LocalException e) { + sendInternalError(pd); + return; } } else { writeLog("File requested not found: `" + filename + "` " + Arrays.binarySearch(fileList, filename), LogLevel.Debug); diff --git a/src/serverP2P/ServerManagementTCP.java b/src/serverP2P/ServerManagementTCP.java index 01be104..da84132 100644 --- a/src/serverP2P/ServerManagementTCP.java +++ b/src/serverP2P/ServerManagementTCP.java @@ -82,6 +82,10 @@ public class ServerManagementTCP extends ServerManagement { Thread flwt = new Thread(fileListWatcher); flwt.start(); fileListWatcher.setThread(flwt); + ratioWatcher = (RatioWatcher)new RatioWatcherTCP(logger, 10000, tracker); + Thread rwt = new Thread(ratioWatcher); + rwt.start(); + ratioWatcher.setThread(rwt); while(!stop) { try { Socket s = socket.accept(); diff --git a/src/serverP2P/ServerManagementUDP.java b/src/serverP2P/ServerManagementUDP.java index 52aa88e..7e541a9 100644 --- a/src/serverP2P/ServerManagementUDP.java +++ b/src/serverP2P/ServerManagementUDP.java @@ -77,6 +77,10 @@ public class ServerManagementUDP extends ServerManagement { Thread flwt = new Thread(fileListWatcher); flwt.start(); fileListWatcher.setThread(flwt); + ratioWatcher = (RatioWatcher)new RatioWatcherUDP(logger, 10000, tracker); + Thread rwt = new Thread(ratioWatcher); + rwt.start(); + ratioWatcher.setThread(rwt); while(!stop) { try { ProtocolP2PPacketUDP pd = new ProtocolP2PPacketUDP<>((Object)socket); diff --git a/src/tools/HostItem.java b/src/tools/HostItem.java index 95960af..3467a73 100644 --- a/src/tools/HostItem.java +++ b/src/tools/HostItem.java @@ -128,7 +128,7 @@ public class HostItem { boolean result = false; if (other instanceof HostItem) { HostItem that = (HostItem) other; - result = this.getHostname() == that.getHostname() && this.getPort() == that.getPort(); + result = this.getHostname().equals(that.getHostname()) && this.getPort() == that.getPort(); } return result; } diff --git a/src/tracker/TrackerManagement.java b/src/tracker/TrackerManagement.java index ab87305..4d1a37a 100644 --- a/src/tracker/TrackerManagement.java +++ b/src/tracker/TrackerManagement.java @@ -79,8 +79,14 @@ public abstract class TrackerManagement extends ServeErrors implements Runnable sendInternalError(pd); } else { HostItem host = ((RatioRequest)p).getHostItem(); + writeLog("Ratio request for host " + host, LogLevel.Debug); try { if (!hostList.contains(host)) { + String l = ""; + for (HostItem h: hostList) { + l += h + " "; + } + writeLog(host + " is not in hostlist [ " + l + "]", LogLevel.Debug); pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.UNKNOWN_HOST))); } else { pd.sendResponse(createProtocolP2PPacket(new RatioResponse(host,