diff options
author | Björn Hagemeister | 2014-06-30 17:42:38 +0200 |
---|---|---|
committer | Björn Hagemeister | 2014-06-30 17:42:38 +0200 |
commit | 76deaa2d682d3be600f6ceb5925e2cf7b20644da (patch) | |
tree | 99f549f072848f894e5d32baf04bff40eb823d38 /src/main/java/org/openslx/filetransfer | |
parent | Merge branch 'master' of git.openslx.org:bwlp/master-sync-shared (diff) | |
download | master-sync-shared-76deaa2d682d3be600f6ceb5925e2cf7b20644da.tar.gz master-sync-shared-76deaa2d682d3be600f6ceb5925e2cf7b20644da.tar.xz master-sync-shared-76deaa2d682d3be600f6ceb5925e2cf7b20644da.zip |
Added filetransfer classes. Downloader.java, Uploader.java, Listener.java and IncomingEvent.java
Diffstat (limited to 'src/main/java/org/openslx/filetransfer')
4 files changed, 608 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/filetransfer/Downloader.java b/src/main/java/org/openslx/filetransfer/Downloader.java new file mode 100644 index 0000000..171f3ae --- /dev/null +++ b/src/main/java/org/openslx/filetransfer/Downloader.java @@ -0,0 +1,256 @@ +package org.openslx.filetransfer; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +public class Downloader { + // Some instance variables. + private SSLSocketFactory sslSocketFactory; + private SSLSocket satelliteSocket; + private DataOutputStream dataToServer; + private DataInputStream dataFromServer; + private String TOKEN = null; + private String RANGE = null; + private static String pathToTrustStore = + "/home/bjoern/javadev/DataTransfer/mySrvKeyStore.jks"; + private String outputFilename; + + /***********************************************************************//** + * Constructor for satellite downloader. + * Tries to connect to specific ip and port and sending type of action. + * @param ip + * @param port + * @throws IOException + * @throws KeyStoreException + * @throws CertificateException + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + */ + public Downloader(String ip, int port, String filename, SSLContext context) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, KeyManagementException { + outputFilename = filename; + + /* + char[] passphrase = "test123".toCharArray(); + KeyStore keystore = KeyStore.getInstance("JKS"); + keystore.load(new FileInputStream(pathToTrustStore), passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keystore); + + SSLContext context = SSLContext.getInstance("SSLv3"); + TrustManager[] trustManagers = tmf.getTrustManagers(); + + context.init(null, trustManagers, null); + */ + + // create socket. + sslSocketFactory = context.getSocketFactory(); + + satelliteSocket = (SSLSocket) sslSocketFactory.createSocket(ip, port); + + dataToServer = new DataOutputStream(satelliteSocket.getOutputStream()); + dataToServer.writeByte('D'); + dataFromServer = new DataInputStream(satelliteSocket.getInputStream()); + } + + /***********************************************************************//** + * Constructor for master downloader. + * Given parameter is the socket over which the transfer is going. + * @param socket + * @throws IOException + */ + public Downloader(SSLSocket socket, String filename) throws IOException { + outputFilename = filename; + satelliteSocket = socket; + dataToServer = new DataOutputStream(satelliteSocket.getOutputStream()); + dataFromServer = new DataInputStream(satelliteSocket.getInputStream()); + } + + /***********************************************************************//** + * Method for sending token for identification from satellite to master. + * @param t + * @throws IOException + */ + public void sendToken(String token) throws IOException { + TOKEN = token; + String sendToken = "TOKEN=" + TOKEN; + byte[] data = sendToken.getBytes(StandardCharsets.UTF_8); + dataToServer.writeByte(data.length); + dataToServer.write(data); + } + + /***********************************************************************//** + * Method to send range of the file, which should be uploaded. + * Helpful for knowing how much was already uploaded if + * connection aborts. + * @param a + * @param b + * @throws IOException + */ + public void sendRange(int a, int b) throws IOException { + RANGE = a + ":" + b; + String sendRange = "RANGE=" + RANGE; + byte[] data = sendRange.getBytes(StandardCharsets.UTF_8); + dataToServer.writeByte(data.length); + dataToServer.write(data); + } + + /***********************************************************************//** + * Method for reading incoming token for identification. + * @throws IOException + */ + public String getToken() throws IOException { + if (TOKEN != null) + return TOKEN; + return null; + } + + /***********************************************************************//** + * Method for reading range of file, which is downloaded. + * Helpful for knowing how much is already downloaded if connection aborts. + */ + public String getRange() { + if (RANGE != null) + return RANGE; + return null; + } + + /***********************************************************************//** + * Getter for beginning of RANGE. + * @return + */ + public int getStartOfRange() { + if (RANGE != null) { + String[] splitted = RANGE.split(":"); + return Integer.parseInt(splitted[0]); + } + return -1; + } + + /***********************************************************************//** + * Getter for end of RANGE. + * @return + */ + public int getEndOfRange() { + if (RANGE != null) { + String[] splitted = RANGE.split(":"); + return Integer.parseInt(splitted[1]); + } + return -1; + } + + /***********************************************************************//** + * Method for returning difference of current Range. + * @return + */ + public int getDiffOfRange() { + int diff = Math.abs(getEndOfRange() - getStartOfRange()); + return diff; + } + + /***********************************************************************//** + * Method for reading MetaData, like TOKEN and FileRange. + * Split incoming bytes after first '=' and store value to specific + * variable. + * @throws IOException + */ + public Boolean readMetaData() throws IOException { + try { + while (true) { + byte[] incoming = new byte[255]; + + // First get length. + dataFromServer.read(incoming, 0, 1); + int length = incoming[0]; + System.out.println("length: " + length); + + if (length == 0) + break; + + /** + * Read the next available bytes and split by '=' for + * getting TOKEN or RANGE. + */ + int hasRead = 0; + while (hasRead < length) { + int ret = dataFromServer.read(incoming, hasRead, length - hasRead); + if (ret == -1) { + System.out.println("Error occured while reading Metadata."); + return false; + } + hasRead += ret; + } + + String data = new String(incoming, 0, length, "UTF-8"); + // System.out.println(data); + + String[] splitted = data.split("="); + // System.out.println("splitted[0]: " + splitted[0]); + // System.out.println("splitted[1]: " + splitted[1]); + if (splitted[0] != null && splitted[0].equals("TOKEN")) { + if (splitted[1] != null) + TOKEN = splitted[1]; + System.out.println("TOKEN: " + TOKEN); + } + else if (splitted[0].equals("RANGE")) { + if (splitted[1] != null) + RANGE = splitted[1]; + System.out.println("RANGE: '" + RANGE + "'"); + } + } + } catch (IOException e) { + throw e; + // return false; + } + return true; + } + + /***********************************************************************//** + * Method for reading Binary. Reading the current Range of incoming binary. + * @throws IOException + */ + public Boolean readBinary() throws IOException { + int length = getDiffOfRange(); + byte[] incoming = new byte[4000]; + + int hasRead = 0; + while (hasRead < length) { + int ret = dataFromServer.read(incoming, hasRead, length - hasRead); + if (ret == -1) { + System.out.println("Error occured in Downloader.readBinary()," + + " while reading binary."); + return false; + } + hasRead += ret; + } + + RandomAccessFile file = new RandomAccessFile(new File(outputFilename), "rw"); + file.seek(getStartOfRange()); + file.write(incoming, 0, length); + file.close(); + return true; + } + + /***********************************************************************//** + * Method for closing connection, if download has finished. + */ + public void close() { + + } +} diff --git a/src/main/java/org/openslx/filetransfer/IncomingEvent.java b/src/main/java/org/openslx/filetransfer/IncomingEvent.java new file mode 100644 index 0000000..a1e8b9e --- /dev/null +++ b/src/main/java/org/openslx/filetransfer/IncomingEvent.java @@ -0,0 +1,13 @@ +package org.openslx.filetransfer; + +import java.io.IOException; + +/***************************************************************************//** + * IncomingEvent interface for handling what should happen with incoming + * uploader or downloader in Listener. Must be implemented outside. + * @author bjoern + */ +public interface IncomingEvent { + void incomingUploader(Uploader uploader) throws IOException; + void incomingDownloader(Downloader downloader) throws IOException; +} diff --git a/src/main/java/org/openslx/filetransfer/Listener.java b/src/main/java/org/openslx/filetransfer/Listener.java new file mode 100644 index 0000000..577bde7 --- /dev/null +++ b/src/main/java/org/openslx/filetransfer/Listener.java @@ -0,0 +1,86 @@ +package org.openslx.filetransfer; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.KeyManagementException; + +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; +import javax.net.ssl.SSLSocket; + +public class Listener { + private IncomingEvent incomingEvent; + /* + private static String pathToKeyStore = + "/home/bjoern/javadev/DataTransfer/mySrvKeyStore.jks"; + */ + private SSLContext context; + + + /***********************************************************************//** + * Constructor for class Listener, which gets an instance of IncomingEvent. + * @param e + */ + public Listener(IncomingEvent e, SSLContext context) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, KeyManagementException, UnrecoverableKeyException { + this.incomingEvent = e; + this.context = context; + /* + char[] passphrase = "test123".toCharArray(); + KeyStore keystore = KeyStore.getInstance("JKS"); + keystore.load(new FileInputStream(pathToKeyStore), passphrase); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keystore, passphrase); + context = SSLContext.getInstance("SSLv3"); + KeyManager[] keyManagers = kmf.getKeyManagers(); + + context.init(keyManagers, null, null); + */ + } + + /***********************************************************************//** + * Method listen, should run from Master Server. Listen for incoming + * connection, and start Downloader or Uploader. + * @throws Exception + */ + public void listen() throws Exception { + SSLServerSocketFactory sslServerSocketFactory = context.getServerSocketFactory(); + SSLServerSocket welcomeSocket = + (SSLServerSocket) sslServerSocketFactory.createServerSocket(6789); + + while (true) { + SSLSocket connectionSocket = (SSLSocket) welcomeSocket.accept(); + + byte[] b = new byte[1]; + int length = connectionSocket.getInputStream().read(b); + + System.out.println(length); + + // Ascii - Code: 'U' = 85 ; 'D' = 68. + if (b[0] == 85) { + System.out.println("U erkannt --> Downloader starten"); + // --> start Downloader(socket). + String filename = "output.txt"; + Downloader d = new Downloader(connectionSocket, filename); + incomingEvent.incomingDownloader(d); + } + else if (b[0] == 68) { + System.out.println("D erkannt --> Uploader starten"); + // --> start Uploader(socket). + Uploader u = new Uploader(connectionSocket); + incomingEvent.incomingUploader(u); + + } + else { + System.out.println("Müll empfangen"); + connectionSocket.close(); + } + } + } +} diff --git a/src/main/java/org/openslx/filetransfer/Uploader.java b/src/main/java/org/openslx/filetransfer/Uploader.java new file mode 100644 index 0000000..103e1bb --- /dev/null +++ b/src/main/java/org/openslx/filetransfer/Uploader.java @@ -0,0 +1,253 @@ +package org.openslx.filetransfer; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.net.UnknownHostException; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +public class Uploader { + // Some member variables. + private SSLSocketFactory sslSocketFactory; + private SSLSocket satelliteSocket; + private DataOutputStream dataToServer; + private DataInputStream dataFromServer; + private String TOKEN = null; + private String RANGE = null; + + private static String pathToTrustStore = + "/home/bjoern/javadev/DataTransfer/mySrvKeyStore.jks"; + + + + /***********************************************************************//** + * Constructor for satellite uploader. + * Tries to connect to specific ip and port and sending type of action. + * @param ip + * @param port + * @throws IOException + * @throws KeyStoreException + * @throws CertificateException + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + * @throws UnknownHostException + */ + public Uploader(String ip, int port) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, KeyManagementException { + char[] passphrase = "test123".toCharArray(); + + KeyStore keystore = KeyStore.getInstance("JKS"); + keystore.load(new FileInputStream(pathToTrustStore), passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keystore); + + SSLContext context = SSLContext.getInstance("SSLv3"); + TrustManager[] trustManagers = tmf.getTrustManagers(); + + context.init(null, trustManagers, null); + + sslSocketFactory = context.getSocketFactory(); + + satelliteSocket = (SSLSocket) sslSocketFactory.createSocket(ip, port); + + dataToServer = new DataOutputStream(satelliteSocket.getOutputStream()); + dataToServer.writeByte('U'); + dataFromServer = new DataInputStream(satelliteSocket.getInputStream()); + } + + /***********************************************************************//** + * Constructor for master uploader. + * Sends back the socket for datatransfer. + * @throws IOException + */ + public Uploader(SSLSocket socket) throws IOException { + satelliteSocket = socket; + dataToServer = new DataOutputStream(satelliteSocket.getOutputStream()); + dataFromServer = new DataInputStream(satelliteSocket.getInputStream()); + } + + /***********************************************************************//** + * Method for sending token from satellite to master. + * Needfull for getting to know what should happens over connection. + * @param t + */ + public void sendToken(String token) throws IOException { + TOKEN = token; + String sendToken = "TOKEN=" + TOKEN; + byte[] data = sendToken.getBytes(StandardCharsets.UTF_8); + dataToServer.writeByte(data.length); + dataToServer.write(data); + } + + /***********************************************************************//** + * Getter for TOKEN. + */ + public String getToken() { + if (TOKEN != null) + return TOKEN; + return null; + } + + /***********************************************************************//** + * Method to send range of the file, which should be uploaded. + * Helpful for knowing how much was already uploaded if + * connection aborts. + * @param a + * @param b + * @throws IOException + */ + public void sendRange(int a, int b) throws IOException { + RANGE = a + ":" + b; + String sendRange = "RANGE=" + RANGE; + byte[] data = sendRange.getBytes(StandardCharsets.UTF_8); + dataToServer.writeByte(data.length); + dataToServer.write(data); + dataToServer.writeByte(0); + } + + /***********************************************************************//** + * Getter for RANGE. + * @return + */ + public String getRange() { + if (RANGE != null) + return RANGE; + return null; + } + + /***********************************************************************//** + * Getter for beginning of RANGE. + * @return + */ + public int getStartOfRange() { + if (RANGE != null) { + String[] splitted = RANGE.split(":"); + return Integer.parseInt(splitted[0]); + } + return -1; + } + + /***********************************************************************//** + * Getter for end of RANGE. + * @return + */ + public int getEndOfRange() { + if (RANGE != null) { + String[] splitted = RANGE.split(":"); + return Integer.parseInt(splitted[1]); + } + return -1; + } + + /***********************************************************************//** + * Method for returning difference of current Range. + * @return + */ + public int getDiffOfRange() { + if (getStartOfRange() == -1 || getEndOfRange() == -1) { + return -1; + } + int diff = Math.abs(getEndOfRange() - getStartOfRange()); + return diff; + } + + /***********************************************************************//** + * Method for reading MetaData, like TOKEN and FileRange. + * Split incoming bytes after first '=' and store value to specific + * variable. + * @throws IOException + */ + public Boolean readMetaData() { + try { + while (true) { + byte[] incoming = new byte[255]; + + // First get length. + dataFromServer.read(incoming, 0, 1); + int length = incoming[0]; + // System.out.println("length: " + length); + + if (length == 0) // Stop if 0 was read. + break; + + /** + * Read the next available bytes and split by '=' for + * getting TOKEN or RANGE. + */ + int hasRead = 0; + while (hasRead < length) { + int ret = dataFromServer.read(incoming, hasRead, length - hasRead); + if (ret == -1) { + System.out.println("Error in reading Metadata occured!"); + return false; + } + hasRead += ret; + } + String data = new String(incoming, "UTF-8"); + // System.out.println(data); + + String[] splitted = data.split("="); + // System.out.println("splitted[0]: " + splitted[0]); + // System.out.println("splitted[1]: " + splitted[1]); + if (splitted[0] != null && splitted[0].equals("TOKEN")) { + if (splitted[1] != null) + TOKEN = splitted[1]; + System.out.println("TOKEN: " + TOKEN); + } + else if (splitted[0].equals("RANGE")) { + if (splitted[1] != null) + RANGE = splitted[1]; + System.out.println("RANGE: " + RANGE); + } + } + } catch (IOException e) { + return false; + } + return true; + } + + /***********************************************************************//** + * Method for sending File with filename. + * @param filename + * @throws IOException + */ + public void sendFile(String filename) throws IOException { + RandomAccessFile file = new RandomAccessFile(new File(filename), "r"); + if (getStartOfRange() == -1) { + file.close(); + return; + } + file.seek(getStartOfRange()); + + byte[] data = new byte[255]; + int hasRead = 0; + int length = getDiffOfRange(); + System.out.println("diff of Range: " + length); + while (hasRead < length) { + int ret = file.read(data, hasRead, length - hasRead); + if (ret == -1) { + System.out.println("Error occured in Uploader.sendFile()," + + " while reading from File to send."); + file.close(); + return; + } + hasRead += ret; + } + file.close(); + dataToServer.write(data, 0, length); + } +} |