diff options
Diffstat (limited to 'src/main/java/org/openslx/filetransfer/Downloader.java')
-rw-r--r-- | src/main/java/org/openslx/filetransfer/Downloader.java | 322 |
1 files changed, 29 insertions, 293 deletions
diff --git a/src/main/java/org/openslx/filetransfer/Downloader.java b/src/main/java/org/openslx/filetransfer/Downloader.java index c860f5e..da882b9 100644 --- a/src/main/java/org/openslx/filetransfer/Downloader.java +++ b/src/main/java/org/openslx/filetransfer/Downloader.java @@ -1,74 +1,46 @@ package org.openslx.filetransfer; -import java.io.DataInputStream; -import java.io.DataOutputStream; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.net.SocketTimeoutException; -import java.nio.charset.StandardCharsets; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; import org.apache.log4j.Logger; -public class Downloader +public class Downloader extends Transfer { // Some instance variables. - private SSLSocketFactory sslSocketFactory; - private SSLSocket satelliteSocket; - private DataOutputStream dataToServer; - private DataInputStream dataFromServer; - private String TOKEN = null; - private String RANGE = null; private String outputFilename = null; - private String ERROR = null; - private static Logger log = Logger.getLogger( Downloader.class ); + private static final Logger log = Logger.getLogger( Downloader.class ); /***********************************************************************/ /** - * Constructor for satellite downloader. - * Tries to connect to specific ip and port and sending type of action. + * Actively initiate a connection to a remote peer for downloading. * - * @param ip - * @param port + * @param host Host name or address to connect to + * @param port Port to connect to + * @throws IOException */ - public Downloader( String ip, int port, SSLContext context ) + public Downloader( String host, int port, SSLContext context ) throws IOException { - try { - // create socket. - sslSocketFactory = context.getSocketFactory(); - - satelliteSocket = (SSLSocket)sslSocketFactory.createSocket( ip, port ); - satelliteSocket.setSoTimeout( 2000 ); // set socket timeout. - - dataToServer = new DataOutputStream( satelliteSocket.getOutputStream() ); - dataToServer.writeByte( 'D' ); - dataFromServer = new DataInputStream( satelliteSocket.getInputStream() ); - } catch ( Exception e ) { - e.printStackTrace(); - } + super( host, port, context, log ); + dataToServer.writeByte( 'D' ); } /***********************************************************************/ /** - * Constructor for master downloader. - * Given parameter is the socket over which the transfer is going. + * Constructor used by Listener to create an incoming download connection. * - * @param socket + * @param socket established connection to peer which requested an upload. + * @throws IOException */ - public Downloader( SSLSocket socket ) + protected Downloader( SSLSocket socket ) throws IOException { - try { - satelliteSocket = socket; - dataToServer = new DataOutputStream( satelliteSocket.getOutputStream() ); - dataFromServer = new DataInputStream( satelliteSocket.getInputStream() ); - } catch ( IOException e ) { - e.printStackTrace(); - } + super( socket, log ); } /***********************************************************************/ @@ -95,211 +67,16 @@ public class Downloader /***********************************************************************/ /** - * Method for sending token for identification from satellite to master. - * - * @param t - */ - public Boolean sendToken( String token ) - { - try { - TOKEN = token; - String sendToken = "TOKEN=" + TOKEN; - byte[] data = sendToken.getBytes( StandardCharsets.UTF_8 ); - dataToServer.writeByte( data.length ); - dataToServer.write( data ); - } catch ( SocketTimeoutException ste ) { - ste.printStackTrace(); - log.info( "Socket timeout occured ... close connection." ); - this.close(); - } catch ( IOException e ) { - e.printStackTrace(); - readMetaData(); - if ( ERROR != null ) { - if ( ERROR == "timeout" ) { - log.info( "Socket timeout occured ... close connection." ); - this.close(); - } - } - log.info( "Sending TOKEN in Downloader failed..." ); - return false; - } - return true; - } - - /***********************************************************************/ - /** - * 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 - */ - public Boolean sendRange( int a, int b ) - { - try { - RANGE = a + ":" + b; - String sendRange = "RANGE=" + RANGE; - byte[] data = sendRange.getBytes( StandardCharsets.UTF_8 ); - dataToServer.writeByte( data.length ); - dataToServer.write( data ); - } catch ( SocketTimeoutException ste ) { - ste.printStackTrace(); - log.info( "Socket timeout occured ... close connection." ); - this.close(); - } catch ( IOException e ) { - e.printStackTrace(); - readMetaData(); - if ( ERROR != null ) { - if ( ERROR == "timeout" ) { - log.info( "Socket timeout occured ... close connection." ); - this.close(); - } - } - log.info( "Sending RANGE in Uploader failed..." ); - return false; - } - return true; - } - - /***********************************************************************/ - /** - * Method for reading incoming token for identification. + * Method to request a byte range within the file to download. This + * method is called by the party that initiated the connection. * + * @param startOffset offset in file where to start the transfer (inclusive) + * @param endOffset end offset where to end the transfer (exclusive) + * @return success or failure */ - public String getToken() + public boolean requestRange( int startOffset, int endOffset ) { - return TOKEN; - } - - /***********************************************************************/ - /** - * Method for reading range of file, which is downloaded. - * Helpful for knowing how much is already downloaded if connection aborts. - */ - public String getRange() - { - return RANGE; - } - - /***********************************************************************/ - /** - * 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. - * - */ - public Boolean readMetaData() - { - try { - while ( true ) { - byte[] incoming = new byte[ 255 ]; // TODO: problematische Größe. - - // First get length. - int retLengthByte; - retLengthByte = dataFromServer.read( incoming, 0, 1 ); - if (retLengthByte != 1) { - this.close(); - return false; - } - - int length = incoming[0] & 0xFF; - log.info( "length (downloader): " + 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 ) { - log.info( "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]; - log.info( "TOKEN: " + TOKEN ); - } - else if ( splitted[0].equals( "RANGE" ) ) { - if ( splitted[1] != null ) - RANGE = splitted[1]; - log.info( "RANGE: '" + RANGE + "'" ); - } - else if ( splitted[0].equals( "ERROR" ) ) { - if ( splitted[1] != null ) - ERROR = splitted[1]; - log.info( "ERROR: " + ERROR ); - return false; - } - } - } catch ( SocketTimeoutException ste ) { - ste.printStackTrace(); - sendErrorCode( "timeout" ); - log.info( "Socket Timeout occured in Downloader." ); - this.close(); - return false; - } catch ( Exception e ) { - e.printStackTrace(); - this.close(); - return false; - } - return true; + return super.sendRange( startOffset, endOffset ); } /***********************************************************************/ @@ -307,21 +84,20 @@ public class Downloader * Method for reading Binary. Reading the current Range of incoming binary. * */ - public Boolean readBinary() + public boolean receiveBinary() { RandomAccessFile file = null; try { - int length = getDiffOfRange(); - byte[] incoming = new byte[ 4000 ]; + int chunkLength = getDiffOfRange(); + byte[] incoming = new byte[ 64000 ]; int hasRead = 0; file = new RandomAccessFile( new File( outputFilename ), "rw" ); file.seek( getStartOfRange() ); - while ( hasRead < length ) { - int ret = dataFromServer.read( incoming, 0, Math.min( length - hasRead, incoming.length ) ); + while ( hasRead < chunkLength ) { + int ret = dataFromServer.read( incoming, 0, Math.min( chunkLength - hasRead, incoming.length ) ); // log.info("hasRead: " + hasRead + " length: " + length + " ret: " + ret); if ( ret == -1 ) { - log.info( "Error occured in Downloader.readBinary()," - + " while reading binary." ); + log.info( "Error occured while receiving payload." ); return false; } hasRead += ret; @@ -333,6 +109,7 @@ public class Downloader sendErrorCode( "timeout" ); log.info( "Socket timeout occured ... close connection." ); this.close(); + return false; } catch ( Exception e ) { e.printStackTrace(); log.info( "Reading RANGE " + getStartOfRange() + ":" + getEndOfRange() @@ -347,49 +124,8 @@ public class Downloader e.printStackTrace(); } } + RANGE = null; // Reset range for next iteration } return true; } - - /***********************************************************************/ - /** - * Method for sending error Code to server. For example in case of wrong - * token, send code for wrong token. - * - */ - public Boolean sendErrorCode( String errString ) - { - try { - String sendError = "ERROR=" + errString; - byte[] data = sendError.getBytes( StandardCharsets.UTF_8 ); - dataToServer.writeByte( data.length ); - dataToServer.write( data ); - } catch ( IOException e ) { - e.printStackTrace(); - this.close(); - return false; - } - return true; - } - - /***********************************************************************/ - /** - * Method for closing connection, if download has finished. - * - */ - public void close() - { - try { - if ( satelliteSocket != null ) { - this.satelliteSocket.close(); - satelliteSocket = null; - } - if ( dataFromServer != null ) - dataFromServer.close(); - if ( dataToServer != null ) - dataToServer.close(); - } catch ( IOException e ) { - e.printStackTrace(); - } - } } |