|
|
|
package clientP2P;
|
|
|
|
import exception.NotFound;
|
|
|
|
import exception.ProtocolError;
|
|
|
|
import exception.InternalError;
|
|
|
|
import exception.TransmissionError;
|
|
|
|
import java.util.Scanner;
|
|
|
|
import java.net.InetAddress;
|
|
|
|
import java.net.DatagramPacket;
|
|
|
|
import java.net.DatagramSocket;
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.FileWriter;
|
|
|
|
|
|
|
|
|
|
|
|
/** Implementation of P2P-JAVA-PROJECT VERSION 1.0 protocol for UDP.
|
|
|
|
* @author Louis Royer
|
|
|
|
* @author Flavien Haas
|
|
|
|
* @author JS Auge
|
|
|
|
* @version 1.0
|
|
|
|
*/
|
|
|
|
public class ClientManagementUDP implements Runnable {
|
|
|
|
private String baseDirectory;
|
|
|
|
private int UDPPort;
|
|
|
|
private String host;
|
|
|
|
private final String protocolID = "P2P-JAVA-PROJECT VERSION 1.0";
|
|
|
|
|
|
|
|
|
|
|
|
/** 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 ClientManagementUDP(String baseDirectory, String host, int UDPPort) {
|
|
|
|
this.baseDirectory = baseDirectory;
|
|
|
|
this.host = host;
|
|
|
|
this.UDPPort = UDPPort;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Implementation of Runnable
|
|
|
|
*/
|
|
|
|
public void run() {
|
|
|
|
System.out.println("Files present on the server:");
|
|
|
|
try {
|
|
|
|
String msg = sendMsg(sendListDirectoryRequest());
|
|
|
|
System.out.println(listDirectory(msg));
|
|
|
|
System.out.println("Name of the file to download:");
|
|
|
|
Scanner scanner = new Scanner(System.in);
|
|
|
|
String f = scanner.nextLine();
|
|
|
|
msg = sendMsg(sendDownloadRequest(f));
|
|
|
|
download(msg, f);
|
|
|
|
} catch (TransmissionError e) {
|
|
|
|
System.out.println("Transmission error");
|
|
|
|
} catch (ProtocolError e) {
|
|
|
|
System.out.println("Protocol error");
|
|
|
|
} catch (NotFound e) {
|
|
|
|
System.out.println("File not found");
|
|
|
|
} catch (InternalError e) {
|
|
|
|
System.out.println("Server internal error");
|
|
|
|
} catch (IOException e) {
|
|
|
|
System.out.println("Cannot write to file");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Prepare request to download file
|
|
|
|
* @param filename name of the file to be downloaded
|
|
|
|
* @return request to be send
|
|
|
|
*/
|
|
|
|
private String sendDownloadRequest(String filename) {
|
|
|
|
return protocolID + "\nDOWNLOAD\n" + filename + "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Download file.
|
|
|
|
* @param response Servers's response
|
|
|
|
* @throws NotFound
|
|
|
|
* @throws ProtocolError
|
|
|
|
* @throws InternalError
|
|
|
|
*/
|
|
|
|
private void download(String response, String filename) throws TransmissionError, NotFound, ProtocolError, InternalError, IOException {
|
|
|
|
try {
|
|
|
|
String r[] = response.split("\n");
|
|
|
|
checkProtocolID(r[0]);
|
|
|
|
switch (r[1]) {
|
|
|
|
case "LOAD":
|
|
|
|
int size = Integer.parseInt(r[2]);
|
|
|
|
if (r[3].length() != size - 1) {
|
|
|
|
throw new TransmissionError();
|
|
|
|
}
|
|
|
|
FileWriter fileWriter = new FileWriter(baseDirectory + filename);
|
|
|
|
fileWriter.write(r[3]);
|
|
|
|
fileWriter.close();
|
|
|
|
break;
|
|
|
|
case "NOT FOUND":
|
|
|
|
throw new NotFound();
|
|
|
|
case "INTERNAL ERROR":
|
|
|
|
throw new InternalError();
|
|
|
|
default:
|
|
|
|
System.out.println("Error: Unknow format `" + r[1] + "`");
|
|
|
|
throw new ProtocolError();
|
|
|
|
}
|
|
|
|
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
|
|
|
|
System.out.println("Error: IndexOutOfBonds");
|
|
|
|
throw new ProtocolError();
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
System.out.println("Error: NumberFormat");
|
|
|
|
throw new ProtocolError();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Prepare request to list files on server
|
|
|
|
* @return request to be send
|
|
|
|
*/
|
|
|
|
private String sendListDirectoryRequest() {
|
|
|
|
return protocolID + "\nLIST\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Parse list of directory response from server
|
|
|
|
* @param response server's response
|
|
|
|
* @return list of files, separated by CRLF
|
|
|
|
* @throws ProtocolError
|
|
|
|
*/
|
|
|
|
private String listDirectory(String response) throws ProtocolError {
|
|
|
|
try {
|
|
|
|
String r[] = response.split("\n");
|
|
|
|
checkProtocolID(r[0]);
|
|
|
|
return response.split(protocolID + "\nLIST\n")[1].split("\n\n")[0];
|
|
|
|
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
|
|
|
|
throw new ProtocolError();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Check client's protocol identifier matches message's protocol identifier.
|
|
|
|
* Throws a ProtocolError if mismatched.
|
|
|
|
* @param msgProtocolID part of the request containing protocol identifier
|
|
|
|
* @throws ProtocolError
|
|
|
|
*/
|
|
|
|
private void checkProtocolID(String msgProtocolID) throws ProtocolError {
|
|
|
|
if (!protocolID.equals(msgProtocolID)) {
|
|
|
|
throw new ProtocolError();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Send message to server
|
|
|
|
* @param msg message to be send
|
|
|
|
* @return server's response
|
|
|
|
*/
|
|
|
|
private String sendMsg(String msg) throws TransmissionError {
|
|
|
|
//TODO changer le gros try catch
|
|
|
|
try{
|
|
|
|
InetAddress dst = InetAddress.getByName(host);
|
|
|
|
byte [] buffer = msg.getBytes();
|
|
|
|
byte [] buffer2 = new byte[1500];
|
|
|
|
DatagramSocket socket = new DatagramSocket();
|
|
|
|
DatagramPacket reception = new DatagramPacket(buffer2, 1500);
|
|
|
|
DatagramPacket emission = new DatagramPacket(buffer, buffer.length, dst, UDPPort);
|
|
|
|
socket.send(emission);
|
|
|
|
socket.receive(reception);
|
|
|
|
return new String(reception.getData(), 0, reception.getLength());
|
|
|
|
} catch (Exception e){
|
|
|
|
System.out.println(e);
|
|
|
|
throw new TransmissionError();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|