diff --git a/.gitignore b/.gitignore index f68d109..72be876 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ out/ !**/src/main/**/out/ !**/src/test/**/out/ +in/ +write/ + ### Eclipse ### .apt_generated .classpath diff --git a/out-ihaveafile.txt b/out-ihaveafile.txt new file mode 100644 index 0000000..08a24f2 --- /dev/null +++ b/out-ihaveafile.txt @@ -0,0 +1 @@ +this is a test file which i can check for errors with diff --git a/src/client/Client.java b/src/client/Client.java index 63e32b0..9bec707 100644 --- a/src/client/Client.java +++ b/src/client/Client.java @@ -1,11 +1,71 @@ package client; +import server.Server; +import shared.ExceptionLogger; +import shared.FileHeader; + +import java.io.*; +import java.net.Socket; +import java.util.*; + public class Client { + public static class ClientInvalidUsageException extends RuntimeException { + public ClientInvalidUsageException(String str){ + super(str); + } + } + + private final Socket serverConnection; + private final DataOutputStream out; + private final DataInputStream in; + + public Client(String address, int port) throws IOException { + serverConnection = new Socket(address, port); + out = new DataOutputStream(new BufferedOutputStream(serverConnection.getOutputStream())); + in = new DataInputStream(new BufferedInputStream(serverConnection.getInputStream())); + } + + void sendFile(String path){ + if (new File(path).isDirectory()) + throw new ClientInvalidUsageException("Unable to send directory. Did you mean sendDir()?"); + System.out.println("Sending path " + path); + new FileHeader(path).write(out); + try { + out.flush(); + } catch (IOException e) { + ExceptionLogger.log(e); + } + } + + void sendDir(String path){ + File p = new File(path); + ArrayDeque filesToCheck = new ArrayDeque<>(Arrays.asList(Objects.requireNonNull(p.listFiles()))); + while (!filesToCheck.isEmpty()) { + File f = filesToCheck.remove(); + if (f.isDirectory()){ + filesToCheck.add(f); + } else + sendFile(f.getPath()); + } + } + + void close(){ + try { + in.close(); + out.close(); + serverConnection.close(); + } catch (Exception e){ + ExceptionLogger.log(e); + } + } + public static void main(String[] args) { - - - + try { + new Client("localhost", Server.SERVER_PORT).sendDir("in/"); + } catch (Exception e){ + ExceptionLogger.log(e); + } } } diff --git a/src/server/Connection.java b/src/server/Connection.java index 08cc3e0..ff09b13 100644 --- a/src/server/Connection.java +++ b/src/server/Connection.java @@ -1,24 +1,23 @@ package server; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; +import shared.FileHeader; + +import java.io.*; import java.net.Socket; public class Connection extends Thread { private final Socket clientSocket; private final Server server; - private BufferedWriter out; - private BufferedReader in; + private DataOutputStream out; + private DataInputStream in; public Connection(Server server, Socket clientSocket) { this.server = server; this.clientSocket = clientSocket; try { - out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); - in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + out = new DataOutputStream(new BufferedOutputStream(clientSocket.getOutputStream())); + in = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream())); } catch (Exception ignored) { } } @@ -26,7 +25,18 @@ public class Connection extends Thread { @Override public void run() { while (server.isRunning()) { + if (!clientSocket.isConnected()) + break; + try { + if (in.available() > 0) { + byte command = in.readByte(); + if (command == FileHeader.COMMAND.WRITE.type) + FileHeader.receive(in); + } + } catch (IOException e) { + throw new RuntimeException(e); + } } try { out.close(); diff --git a/src/server/Server.java b/src/server/Server.java index 38e5752..7d2cbd1 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -1,5 +1,7 @@ package server; +import shared.ExceptionLogger; + import java.io.IOException; import java.net.ServerSocket; @@ -7,12 +9,11 @@ public class Server { public static final int SERVER_PORT = 42069; - private ServerSocket serverSocket; private volatile boolean running = true; public Server() { try { - serverSocket = new ServerSocket(SERVER_PORT); + ServerSocket serverSocket = new ServerSocket(SERVER_PORT); while (running) { new Connection(this, serverSocket.accept()).start(); @@ -20,12 +21,12 @@ public class Server { serverSocket.close(); } catch (IOException e) { - throw new RuntimeException(e); + ExceptionLogger.log(e); } } public boolean isRunning(){ - return isRunning(); + return running; } public static void main(String[] args) { diff --git a/src/shared/ExceptionLogger.java b/src/shared/ExceptionLogger.java new file mode 100644 index 0000000..e460b62 --- /dev/null +++ b/src/shared/ExceptionLogger.java @@ -0,0 +1,15 @@ +package shared; + +public class ExceptionLogger { + + public static void log(Exception e){ + System.err.println("We have caught an exception:"); + System.err.println("\tCaused by: "); + System.err.println("\t\t" + e.getLocalizedMessage()); + System.err.println("\tStack trace:"); + StackTraceElement[] stack = e.getStackTrace(); + for (StackTraceElement s : stack) + System.err.println("\t\tAt " + s.toString()); + } + +} diff --git a/src/shared/FileHeader.java b/src/shared/FileHeader.java index 25e794a..6c9f41c 100644 --- a/src/shared/FileHeader.java +++ b/src/shared/FileHeader.java @@ -1,6 +1,10 @@ package shared; +import client.Client; + import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; public class FileHeader { @@ -8,9 +12,9 @@ public class FileHeader { public enum COMMAND { WRITE((byte) 1); - private final byte type; + public final byte type; - private COMMAND(byte type) { + COMMAND(byte type) { this.type = type; } } @@ -19,18 +23,22 @@ public class FileHeader { private final String full_path; public FileHeader(String path) { + File pf = new File(path); + if (!pf.exists()) + throw new Client.ClientInvalidUsageException("Unable to send a file which doesn't exist!"); + if (pf.isDirectory()) + throw new Client.ClientInvalidUsageException("Path is a directory unable to send!"); String workingDirectory = System.getProperty("user.dir"); this.full_path = path; this.relative_path = path.replace(workingDirectory, ""); System.out.println(relative_path); - this.size = 0; } - void write(DataOutputStream writer) { + public void write(DataOutputStream writer) { try { - DataInputStream reader = new DataInputStream(new BufferedInputStream(new FileInputStream(full_path))); + DataInputStream reader = new DataInputStream(new BufferedInputStream(Files.newInputStream(Paths.get(full_path)))); - writer.write(COMMAND.WRITE.type); + writer.writeByte(COMMAND.WRITE.type); writer.writeUTF(relative_path); while (reader.available() > 0) { @@ -38,20 +46,44 @@ public class FileHeader { byte[] bytes = new byte[read]; int amount = reader.read(bytes); + if (amount <= 0) + break; + System.out.println("Writing " + amount + " bytes"); writer.writeInt(amount); writer.write(bytes, 0, amount); } - } catch (Exception ignored) { + reader.close(); + writer.writeInt(0); + writer.flush(); + } catch (Exception e) { + ExceptionLogger.log(e); } } - void receive(DataInputStream reader) { + public static void receive(DataInputStream reader) { try { - String relative = reader.readUTF(); + String userFile = reader.readUTF(); + String[] pathParts = userFile.split("/"); + String userDirectory = userFile.replace(pathParts[pathParts.length-1], ""); + File ld = new File(System.getProperty("user.dir") + "/write/" + userDirectory); + if (!ld.exists()) + if(!ld.mkdirs()) + System.out.println("Failed to create directory"); - DataOutputStream writer = new DataOutputStream(new BufferedOutputStream(new FileOutputStream())); - } catch (Exception ignored){ + String path = System.getProperty("user.dir") + "/write/" + userFile; + System.out.println("Writing to file: " + path); + + DataOutputStream writer = new DataOutputStream(new BufferedOutputStream(Files.newOutputStream(Paths.get(path)))); + int size = 0; + while ((size = reader.readInt()) > 0) { + byte[] data = new byte[size]; + int amount = reader.read(data, 0, size); + writer.write(data, 0, amount); + } + writer.flush(); + } catch (Exception e){ + ExceptionLogger.log(e); } }