diff --git a/src/clientP2P/ClientDownload.java b/src/clientP2P/ClientDownload.java index a43a349..282a4d7 100644 --- a/src/clientP2P/ClientDownload.java +++ b/src/clientP2P/ClientDownload.java @@ -43,6 +43,9 @@ import tools.HostItem; import tools.Logger; import tools.LogLevel; import tools.ServeErrors; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.io.IOException; /** Class to download file * @author Louis Royer @@ -111,6 +114,7 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { writeLog(e, LogLevel.Error); } } + writeLog("Downloader stopped", LogLevel.Info); } /** Asks thread to stop @@ -368,6 +372,7 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { /** Runnable implementation */ public void run() { + writeLog("Downloader started", LogLevel.Info); try { init(); purgeList(); @@ -429,8 +434,11 @@ public abstract class ClientDownload extends ServeErrors implements Runnable { /** Getter for HostItem socket * @param hostItem HostItem + * @throws SocketException + * @throws UnknownHostException + * @throws IOException */ - protected abstract Object getHostItemSocket(HostItem hostItem); + protected abstract Object getHostItemSocket(HostItem hostItem) throws SocketException, UnknownHostException, IOException; } diff --git a/src/clientP2P/ClientDownloadTCP.java b/src/clientP2P/ClientDownloadTCP.java index 9be9afe..bacf608 100644 --- a/src/clientP2P/ClientDownloadTCP.java +++ b/src/clientP2P/ClientDownloadTCP.java @@ -35,6 +35,9 @@ import clientP2P.ClientDownload; import tools.HostItem; import tools.Logger; import tools.LogLevel; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.io.IOException; /** Class to download file from tcp * @author Louis Royer @@ -96,8 +99,11 @@ public class ClientDownloadTCP extends ClientDownload { /** Getter for HostItem socket * @param hostItem HostItem + * @throws SocketException + * @throws UnknownHostException + * @throws IOException */ - protected Object getHostItemSocket(HostItem hostItem) { - return (Object)hostItem.getTCPSocket(); + protected Object getHostItemSocket(HostItem hostItem) throws SocketException, UnknownHostException, IOException { + return (Object)hostItem.tryGetTCPSocket(); } } diff --git a/src/clientP2P/ClientDownloadUDP.java b/src/clientP2P/ClientDownloadUDP.java index ce37434..50f4081 100644 --- a/src/clientP2P/ClientDownloadUDP.java +++ b/src/clientP2P/ClientDownloadUDP.java @@ -34,6 +34,9 @@ import clientP2P.ClientDownload; import tools.HostItem; import tools.Logger; import tools.LogLevel; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.io.IOException; /** Class to download file from udp @@ -88,10 +91,13 @@ public class ClientDownloadUDP extends ClientDownload { } /** Getter for HostItem socket - * @param hostItem HostItem + * @param hostItem HostItemç + * @throws SocketException + * @throws UnknownHostException + * @throws IOException */ - protected Object getHostItemSocket(HostItem hostItem) { - return (Object)hostItem.getUDPSocket(); + protected Object getHostItemSocket(HostItem hostItem) throws SocketException, UnknownHostException, IOException { + return (Object)hostItem.tryGetUDPSocket(); } /** Close HostItem socket diff --git a/src/clientP2P/ClientManagement.java b/src/clientP2P/ClientManagement.java index 9cec7bd..637ff44 100644 --- a/src/clientP2P/ClientManagement.java +++ b/src/clientP2P/ClientManagement.java @@ -35,6 +35,7 @@ import tools.ServeErrors; import tools.HostItem; import tools.Logger; import tools.LogLevel; +import java.net.SocketException; /** Implementation of P2P-JAVA-PROJECT CLIENT * @author Louis Royer @@ -77,8 +78,16 @@ public abstract class ClientManagement extends ServeErrors implements Runnable { } /** Getter for tracker socket + * @return Tracker's socket + * @throws SocketException + * @throws UnknownHostException + * @throws IOException + */ + protected abstract Object getTrackerSocket() throws SocketException, UnknownHostException, IOException; + + /** Close Tracker socket */ - protected abstract Object getTrackerSocket(); + protected abstract void closeTrackerSocket(); /** Initialize hostList from tracker @@ -88,7 +97,29 @@ public abstract class ClientManagement extends ServeErrors implements Runnable { private void initHostList() throws ProtocolError, InternalError { ProtocolP2PPacket d = createProtocolP2PPacket(new DiscoverRequest(null)); try { - d.sendRequest(getTrackerSocket()); + boolean contacted = false; + boolean firstLoop = true; + boolean stop = false; + while (!contacted && !stop) { + try { + if (!firstLoop) { + writeLog("Cannot contact tracker. Try again [Y/n] ?", LogLevel.Error); + String tryAgain = scanner.nextLine(); + if (tryAgain.equals("n") || tryAgain.equals("N")) { + stop = true; + } + } + firstLoop = false; + d.sendRequest(getTrackerSocket()); + contacted = true; + } catch (SocketException e) { + } catch (UnknownHostException e) { + } catch (IOException e) { + } + } + if (stop) { + System.exit(3); + } Payload p = d.receiveResponse().getPayload(); assert p instanceof DiscoverResponse : "This payload must be instance of Filelist"; if (!(p instanceof DiscoverResponse)) { @@ -96,6 +127,7 @@ public abstract class ClientManagement extends ServeErrors implements Runnable { } else { hostList = ((DiscoverResponse)p).getHostList(); } + closeTrackerSocket(); } catch (SocketClosed e){ writeLog("listDirectory : SocketClosed", LogLevel.Error); throw new ProtocolError(); @@ -129,6 +161,12 @@ public abstract class ClientManagement extends ServeErrors implements Runnable { */ protected abstract Object getHostItemSocket(HostItem hostItem); + /** Close HostItem socket + * @param hostItem HostItem + */ + protected abstract void closeHostItemSocket(HostItem hostItem); + + /** list server’s directory content * @return list of files * @throws InternalError @@ -148,6 +186,7 @@ public abstract class ClientManagement extends ServeErrors implements Runnable { try { d.sendRequest(getHostItemSocket(hostList.get(0))); Payload p = d.receiveResponse().getPayload(); + closeHostItemSocket(hostList.get(0)); assert p instanceof FileList : "This payload must be instance of Filelist"; if (!(p instanceof FileList)) { throw new InternalError(); @@ -286,5 +325,6 @@ public abstract class ClientManagement extends ServeErrors implements Runnable { writeLog("File is empty", LogLevel.Error); } } + writeLog("Exiting client", LogLevel.Info); } } diff --git a/src/clientP2P/ClientManagementTCP.java b/src/clientP2P/ClientManagementTCP.java index 90f4c71..5372ec8 100644 --- a/src/clientP2P/ClientManagementTCP.java +++ b/src/clientP2P/ClientManagementTCP.java @@ -9,6 +9,9 @@ import tools.Logger; import tools.LogLevel; import clientP2P.ClientDownloadTCP; import clientP2P.ClientManagement; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.io.IOException; /** Implementation of P2P-JAVA-PROJECT CLIENT @@ -63,15 +66,34 @@ public class ClientManagementTCP extends ClientManagement { } /** Getter for tracker socket + * @return Tracker's socket + * @throws SocketException + * @throws UnknownHostException + * @throws IOException */ - protected Object getTrackerSocket() { - return (Object)tracker.getTCPSocket(); + protected Object getTrackerSocket() throws SocketException, UnknownHostException, IOException { + return (Object)tracker.tryGetTCPSocket(); } + /** Close Tracker socket + */ + protected void closeTrackerSocket() { + tracker.closeTCPSocket(); + } + + /** Getter for HostItem socket * @param hostItem HostItem */ protected Object getHostItemSocket(HostItem hostItem) { return (Object)hostItem.getTCPSocket(); } + + /** Close HostItem socket + * @param hostItem HostItem + */ + protected void closeHostItemSocket(HostItem hostItem) { + hostItem.closeTCPSocket(); + } + } diff --git a/src/clientP2P/ClientManagementUDP.java b/src/clientP2P/ClientManagementUDP.java index 224a466..d700587 100644 --- a/src/clientP2P/ClientManagementUDP.java +++ b/src/clientP2P/ClientManagementUDP.java @@ -9,6 +9,9 @@ import tools.Logger; import tools.LogLevel; import clientP2P.ClientDownloadUDP; import clientP2P.ClientManagement; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.io.IOException; /** Implementation of P2P-JAVA-PROJECT CLIENT * @author Louis Royer @@ -60,9 +63,19 @@ public class ClientManagementUDP extends ClientManagement { } /** Getter for tracker socket + * @return Tracker's socket + * @throws SocketException + * @throws UnknownHostException + * @throws IOException */ - protected Object getTrackerSocket() { - return (Object)tracker.getUDPSocket(); + protected Object getTrackerSocket() throws SocketException, UnknownHostException, IOException { + return (Object)tracker.tryGetUDPSocket(); + } + + /** Close Tracker socket + */ + protected void closeTrackerSocket() { + tracker.closeUDPSocket(); } /** Getter for HostItem socket diff --git a/src/serverP2P/FileWatcher.java b/src/serverP2P/FileWatcher.java index 39877d2..6146ed8 100644 --- a/src/serverP2P/FileWatcher.java +++ b/src/serverP2P/FileWatcher.java @@ -88,6 +88,7 @@ public abstract class FileWatcher implements Runnable { setStop(); } } + writeLog("File watcher end of loop", LogLevel.Debug); } /** Register server on tracker diff --git a/src/serverP2P/FileWatcherUDP.java b/src/serverP2P/FileWatcherUDP.java index 194039e..0f206a1 100644 --- a/src/serverP2P/FileWatcherUDP.java +++ b/src/serverP2P/FileWatcherUDP.java @@ -52,7 +52,7 @@ public class FileWatcherUDP extends FileWatcher { try { writeLog("Trying to register into tracker", LogLevel.Info); ProtocolP2PPacket p = (ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Register(server)); - p.sendRequest((Object)tracker.getUDPSocket()); + p.sendRequest((Object)tracker.tryGetUDPSocket()); writeLog("Register request sent (but cannot ensure reception).", LogLevel.Debug); tracker.closeUDPSocket(); } catch (Exception e) { diff --git a/src/serverP2P/RatioWatcher.java b/src/serverP2P/RatioWatcher.java index 884c818..6eeb565 100644 --- a/src/serverP2P/RatioWatcher.java +++ b/src/serverP2P/RatioWatcher.java @@ -60,6 +60,7 @@ public abstract class RatioWatcher implements Runnable { setStop(); } } + writeLog("Ratio watcher end of loop", LogLevel.Debug); } /** Invalidate the cache by cleaning all hashmaps diff --git a/src/serverP2P/ServerManagement.java b/src/serverP2P/ServerManagement.java index af7ed6f..da3be22 100644 --- a/src/serverP2P/ServerManagement.java +++ b/src/serverP2P/ServerManagement.java @@ -68,6 +68,7 @@ public abstract class ServerManagement extends ServeErrors implements Runnable { ratioWatcher.setStop(); sendUnregisterRequest(); closeSocket(); + writeLog("Server stopped", LogLevel.Info); } /** Closes socket */ diff --git a/src/serverP2P/ServerManagementTCP.java b/src/serverP2P/ServerManagementTCP.java index da84132..cbb337e 100644 --- a/src/serverP2P/ServerManagementTCP.java +++ b/src/serverP2P/ServerManagementTCP.java @@ -95,6 +95,7 @@ public class ServerManagementTCP extends ServerManagement { writeLog("Socket has been closed", LogLevel.Info); } } + writeLog("Server end of loop", LogLevel.Debug); } /** Private runnable class allowing to serve one client. @@ -162,6 +163,7 @@ public class ServerManagementTCP extends ServerManagement { } /** Getter for tracker socket + * @return Tracker's socket */ protected Object getTrackerSocket() { return (Object)tracker.getTCPSocket(); diff --git a/src/serverP2P/ServerManagementUDP.java b/src/serverP2P/ServerManagementUDP.java index 7e541a9..1dd7f53 100644 --- a/src/serverP2P/ServerManagementUDP.java +++ b/src/serverP2P/ServerManagementUDP.java @@ -89,6 +89,7 @@ public class ServerManagementUDP extends ServerManagement { } catch (LocalException e) { } } + writeLog("Server end of loop", LogLevel.Debug); } @@ -116,6 +117,7 @@ public class ServerManagementUDP extends ServerManagement { } /** Getter for tracker socket + * @return Tracker's socket */ protected Object getTrackerSocket() { return (Object)tracker.getUDPSocket(); diff --git a/src/tools/HostItem.java b/src/tools/HostItem.java index 0ac3ae1..9808fed 100644 --- a/src/tools/HostItem.java +++ b/src/tools/HostItem.java @@ -32,21 +32,19 @@ public class HostItem { * @return TCP Socket */ public Socket getTCPSocket() { - if (tcpSocket == null || tcpSocket.isClosed()) { - try { - tcpSocket = new Socket(InetAddress.getByName(hostname), port); - } catch (SocketException e) { - System.err.println("getTCPSocket error: No TCP socket available."); - System.exit(-1); - } catch (UnknownHostException e) { - System.err.println("getTCPSocket error: Unknown host (" + this + ")."); - System.exit(-1); - } catch (IOException e) { - System.err.println("getTCPSocket error: Cannot create TCP socket (" + this + ")."); - System.exit(-1); - } + try { + return tryGetTCPSocket(); + } catch (SocketException e) { + System.err.println("getTCPSocket error: No TCP socket available."); + System.exit(-1); + } catch (UnknownHostException e) { + System.err.println("getTCPSocket error: Unknown host (" + this + ")."); + System.exit(-1); + } catch (IOException e) { + System.err.println("getTCPSocket error: Cannot create TCP socket (" + this + ")."); + System.exit(-1); } - return tcpSocket; + return null; // java compiler is stupid and doesn't know about System.exit } /** Get TCP Socket. @@ -79,17 +77,27 @@ public class HostItem { * return UDP Socket */ public DatagramSocket getUDPSocket() { + try { + return tryGetUDPSocket(); + } catch (SocketException e) { + System.err.println("getUDPSocket error: No UDP socket available." ); + System.exit(-1); + } catch (UnknownHostException e) { + System.err.println("getUDPSocket error: Unknown host (" + this + ")."); + System.exit(-1); + } + return null; // java compiler is stupid and doesn't know about System.exit + } + + /** Get UDP Socket. + * @return UDP Socket + * @throws SocketException + * @throws UnknownHostException + */ + public DatagramSocket tryGetUDPSocket() throws SocketException, UnknownHostException { if (udpSocket == null || udpSocket.isClosed()) { - try { - udpSocket = new DatagramSocket(); - udpSocket.connect(InetAddress.getByName(hostname), port); - } catch (SocketException e) { - System.err.println("getUDPSocket error: No UDP socket available." ); - System.exit(-1); - } catch (UnknownHostException e) { - System.err.println("getUDPSocket error: Unknown host (" + this + ")."); - System.exit(-1); - } + udpSocket = new DatagramSocket(); + udpSocket.connect(InetAddress.getByName(hostname), port); } return udpSocket; }