|
|
@ -1,8 +1,8 @@
|
|
|
|
package clientP2P;
|
|
|
|
package clientP2P;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Scanner;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Paths;
|
|
|
|
import java.nio.file.Paths;
|
|
|
@ -31,6 +31,8 @@ import remoteException.ProtocolRemoteError;
|
|
|
|
import remoteException.VersionRemoteError;
|
|
|
|
import remoteException.VersionRemoteError;
|
|
|
|
import remoteException.NotATracker;
|
|
|
|
import remoteException.NotATracker;
|
|
|
|
import remoteException.UnknownHost;
|
|
|
|
import remoteException.UnknownHost;
|
|
|
|
|
|
|
|
import exception.RemoteException;
|
|
|
|
|
|
|
|
import exception.LocalException;
|
|
|
|
import tools.ServeErrors;
|
|
|
|
import tools.ServeErrors;
|
|
|
|
import tools.HostItem;
|
|
|
|
import tools.HostItem;
|
|
|
|
import tools.Logger;
|
|
|
|
import tools.Logger;
|
|
|
@ -43,14 +45,13 @@ import java.net.SocketException;
|
|
|
|
* @author JS Auge
|
|
|
|
* @author JS Auge
|
|
|
|
* @version 1.0
|
|
|
|
* @version 1.0
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public abstract class ClientManagement extends ServeErrors implements Runnable {
|
|
|
|
public abstract class ClientManagement extends ServeErrors {
|
|
|
|
protected String baseDirectory;
|
|
|
|
protected String baseDirectory;
|
|
|
|
protected String partsSubdir;
|
|
|
|
protected String partsSubdir;
|
|
|
|
protected List<HostItem> hostList;
|
|
|
|
protected List<HostItem> hostList = new ArrayList<>();
|
|
|
|
protected HostItem tracker;
|
|
|
|
protected HostItem tracker;
|
|
|
|
protected HostItem client;
|
|
|
|
protected HostItem client;
|
|
|
|
protected Logger logger;
|
|
|
|
protected Logger logger;
|
|
|
|
protected Scanner scanner;
|
|
|
|
|
|
|
|
protected ClientDownload downLoader;
|
|
|
|
protected ClientDownload downLoader;
|
|
|
|
|
|
|
|
|
|
|
|
/** Constructor with baseDirectory, tracker, partsSubdir, logger, and scanner parameters.
|
|
|
|
/** Constructor with baseDirectory, tracker, partsSubdir, logger, and scanner parameters.
|
|
|
@ -58,23 +59,14 @@ public abstract class ClientManagement extends ServeErrors implements Runnable {
|
|
|
|
* @param tracker Tracker hostItem
|
|
|
|
* @param tracker Tracker hostItem
|
|
|
|
* @param partsSubdir subdirectory to store file parts
|
|
|
|
* @param partsSubdir subdirectory to store file parts
|
|
|
|
* @param logger Loggger
|
|
|
|
* @param logger Loggger
|
|
|
|
* @param scanner Scanner used to read input
|
|
|
|
|
|
|
|
* @param client HostItem of the application
|
|
|
|
* @param client HostItem of the application
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public ClientManagement(String baseDirectory, HostItem tracker, String partsSubdir, Logger logger, Scanner scanner, HostItem client) {
|
|
|
|
public ClientManagement(String baseDirectory, HostItem tracker, String partsSubdir, Logger logger, HostItem client) {
|
|
|
|
this.scanner = scanner;
|
|
|
|
|
|
|
|
this.baseDirectory = baseDirectory;
|
|
|
|
this.baseDirectory = baseDirectory;
|
|
|
|
this.tracker = tracker;
|
|
|
|
this.tracker = tracker;
|
|
|
|
this.partsSubdir = partsSubdir;
|
|
|
|
this.partsSubdir = partsSubdir;
|
|
|
|
this.logger = logger;
|
|
|
|
this.logger = logger;
|
|
|
|
this.client = client;
|
|
|
|
this.client = client;
|
|
|
|
try {
|
|
|
|
|
|
|
|
initHostList();
|
|
|
|
|
|
|
|
} catch (InternalError e) {
|
|
|
|
|
|
|
|
System.exit(-1);
|
|
|
|
|
|
|
|
} catch (ProtocolError e) {
|
|
|
|
|
|
|
|
System.exit(-2);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Getter for tracker socket
|
|
|
|
/** Getter for tracker socket
|
|
|
@ -93,33 +85,14 @@ public abstract class ClientManagement extends ServeErrors implements Runnable {
|
|
|
|
/** Initialize hostList from tracker
|
|
|
|
/** Initialize hostList from tracker
|
|
|
|
* @throws ProtocolError
|
|
|
|
* @throws ProtocolError
|
|
|
|
* @throws InternalError
|
|
|
|
* @throws InternalError
|
|
|
|
|
|
|
|
* @throws SocketException
|
|
|
|
|
|
|
|
* @throws UnknownHostException
|
|
|
|
|
|
|
|
* @throws IOException
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private void initHostList() throws ProtocolError, InternalError {
|
|
|
|
public void initHostList() throws ProtocolError, InternalError, SocketException, UnknownHostException, IOException {
|
|
|
|
ProtocolP2PPacket<?> d = createProtocolP2PPacket(new DiscoverRequest(null));
|
|
|
|
ProtocolP2PPacket<?> d = createProtocolP2PPacket(new DiscoverRequest(null));
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
boolean contacted = false;
|
|
|
|
d.sendRequest(getTrackerSocket());
|
|
|
|
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();
|
|
|
|
Payload p = d.receiveResponse().getPayload();
|
|
|
|
assert p instanceof DiscoverResponse : "This payload must be instance of Filelist";
|
|
|
|
assert p instanceof DiscoverResponse : "This payload must be instance of Filelist";
|
|
|
|
if (!(p instanceof DiscoverResponse)) {
|
|
|
|
if (!(p instanceof DiscoverResponse)) {
|
|
|
@ -131,10 +104,10 @@ public abstract class ClientManagement extends ServeErrors implements Runnable {
|
|
|
|
} catch (SocketClosed e){
|
|
|
|
} catch (SocketClosed e){
|
|
|
|
writeLog("listDirectory : SocketClosed", LogLevel.Error);
|
|
|
|
writeLog("listDirectory : SocketClosed", LogLevel.Error);
|
|
|
|
throw new ProtocolError();
|
|
|
|
throw new ProtocolError();
|
|
|
|
} catch (NotATracker e) {
|
|
|
|
} catch (LocalException e) {
|
|
|
|
writeLog(e, LogLevel.Error);
|
|
|
|
writeLog(e, LogLevel.Error);
|
|
|
|
throw new ProtocolError();
|
|
|
|
throw new ProtocolError();
|
|
|
|
} catch (Exception e) {
|
|
|
|
} catch (RemoteException e) {
|
|
|
|
writeLog(e, LogLevel.Error);
|
|
|
|
writeLog(e, LogLevel.Error);
|
|
|
|
throw new ProtocolError();
|
|
|
|
throw new ProtocolError();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -144,7 +117,7 @@ public abstract class ClientManagement extends ServeErrors implements Runnable {
|
|
|
|
* @param filename
|
|
|
|
* @param filename
|
|
|
|
* @return hashsum
|
|
|
|
* @return hashsum
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
protected byte[] computeHashsum(String filename, HashAlgorithm h) {
|
|
|
|
private byte[] computeHashsum(String filename, HashAlgorithm h) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
MessageDigest md = MessageDigest.getInstance(HashAlgorithm.SHA512.getName());
|
|
|
|
MessageDigest md = MessageDigest.getInstance(HashAlgorithm.SHA512.getName());
|
|
|
|
return md.digest(Files.readAllBytes(Paths.get(baseDirectory + filename)));
|
|
|
|
return md.digest(Files.readAllBytes(Paths.get(baseDirectory + filename)));
|
|
|
@ -181,7 +154,7 @@ public abstract class ClientManagement extends ServeErrors implements Runnable {
|
|
|
|
* @throws ProtocolRemoteError
|
|
|
|
* @throws ProtocolRemoteError
|
|
|
|
* @throws VersionRemoteError
|
|
|
|
* @throws VersionRemoteError
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
protected String[] listDirectory() throws EmptyDirectory, InternalError, UnknownHostException, IOException, TransmissionError, ProtocolError, VersionError, SizeError, InternalRemoteError, ProtocolRemoteError, VersionRemoteError {
|
|
|
|
public String[] listDirectory() throws EmptyDirectory, InternalError, UnknownHostException, IOException, TransmissionError, ProtocolError, VersionError, SizeError, InternalRemoteError, ProtocolRemoteError, VersionRemoteError {
|
|
|
|
if (hostList.size() == 0) {
|
|
|
|
if (hostList.size() == 0) {
|
|
|
|
return new String[0];
|
|
|
|
return new String[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -234,7 +207,7 @@ public abstract class ClientManagement extends ServeErrors implements Runnable {
|
|
|
|
* @throws VersionRemoteError
|
|
|
|
* @throws VersionRemoteError
|
|
|
|
* @throws EmptyFile
|
|
|
|
* @throws EmptyFile
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private void download(String filename) throws EmptyFile, NotFound, InternalError, UnknownHostException, IOException, TransmissionError, ProtocolError, VersionError, SizeError, InternalRemoteError, ProtocolRemoteError, VersionRemoteError {
|
|
|
|
public void download(String filename) throws EmptyFile, NotFound, InternalError, UnknownHostException, IOException, TransmissionError, ProtocolError, VersionError, SizeError, InternalRemoteError, ProtocolRemoteError, VersionRemoteError {
|
|
|
|
initDownloader(filename);
|
|
|
|
initDownloader(filename);
|
|
|
|
Thread t = new Thread(downLoader);
|
|
|
|
Thread t = new Thread(downLoader);
|
|
|
|
t.start();
|
|
|
|
t.start();
|
|
|
@ -268,66 +241,17 @@ public abstract class ClientManagement extends ServeErrors implements Runnable {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Implementation of Runnable
|
|
|
|
/** Implementation of writeLog
|
|
|
|
|
|
|
|
* @param text Text to log
|
|
|
|
|
|
|
|
* @param logLevel level of logging
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void run() {
|
|
|
|
protected abstract void writeLog(String text, LogLevel logLevel);
|
|
|
|
boolean isrunning = true;
|
|
|
|
|
|
|
|
while (isrunning){
|
|
|
|
/** Implementation of writeLog
|
|
|
|
try {
|
|
|
|
* @param e exception to log
|
|
|
|
int i = 1;
|
|
|
|
* @param logLevel level of logging
|
|
|
|
String[] list = listDirectory();
|
|
|
|
*/
|
|
|
|
System.out.println("Files present on the server:");
|
|
|
|
protected abstract void writeLog(Exception e, LogLevel logLevel);
|
|
|
|
System.out.println("0 : Exit the program");
|
|
|
|
|
|
|
|
for(String listItem: list) {
|
|
|
|
|
|
|
|
System.out.println(i + " : " + listItem);
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
System.out.println("Type the number associated with the file to download:");
|
|
|
|
|
|
|
|
String f = scanner.nextLine();
|
|
|
|
|
|
|
|
if(f.equals("0")){
|
|
|
|
|
|
|
|
isrunning = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
int j = Integer.parseInt(f);
|
|
|
|
|
|
|
|
if(j <= list.length){
|
|
|
|
|
|
|
|
j--;
|
|
|
|
|
|
|
|
download(list[j]);
|
|
|
|
|
|
|
|
System.out.println("File " + f + " sucessfully downloaded");
|
|
|
|
|
|
|
|
writeLog("File " + f + " sucessfully downloaded", LogLevel.Info);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
System.out.println("File " + f + " unsucessfully downloaded, wrong number");
|
|
|
|
|
|
|
|
writeLog("File " + f + " unsucessfully downloaded, wrong number", LogLevel.Info);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (EmptyDirectory e) {
|
|
|
|
|
|
|
|
writeLog("Server has no file in directory", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (InternalError e) {
|
|
|
|
|
|
|
|
writeLog("Client internal error", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (UnknownHostException e) {
|
|
|
|
|
|
|
|
writeLog("Server host is unknown", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
writeLog("Request cannot be send or response cannot be received", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (TransmissionError e) {
|
|
|
|
|
|
|
|
writeLog("Message received is too big", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (ProtocolError e) {
|
|
|
|
|
|
|
|
writeLog("Cannot decode server’s response", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (VersionError e) {
|
|
|
|
|
|
|
|
writeLog("Server’s response use bad version of the protocol", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (SizeError e) {
|
|
|
|
|
|
|
|
writeLog("Cannot handle this packets because of internal representation limitations of numbers on the client", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (InternalRemoteError e) {
|
|
|
|
|
|
|
|
writeLog("Server internal error", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (ProtocolRemoteError e) {
|
|
|
|
|
|
|
|
writeLog("Server cannot decode client’s request", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (VersionRemoteError e) {
|
|
|
|
|
|
|
|
writeLog("Server cannot decode this version of the protocol", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (NotFound e) {
|
|
|
|
|
|
|
|
writeLog("Server has not this file in directory", LogLevel.Error);
|
|
|
|
|
|
|
|
} catch (EmptyFile e) {
|
|
|
|
|
|
|
|
writeLog("File is empty", LogLevel.Error);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
writeLog("Exiting client", LogLevel.Info);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|