summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/filetransfer/Downloader.java
diff options
context:
space:
mode:
authorNils Schwabe2014-08-28 15:14:26 +0200
committerNils Schwabe2014-08-28 15:14:26 +0200
commitd05168ce96faaad75d79671e1cdf2eaccb884ed9 (patch)
treeb24ae28d98ac368abca6c2e3c9d2c006da0567e9 /src/main/java/org/openslx/filetransfer/Downloader.java
parentUndo test (diff)
downloadmaster-sync-shared-d05168ce96faaad75d79671e1cdf2eaccb884ed9.tar.gz
master-sync-shared-d05168ce96faaad75d79671e1cdf2eaccb884ed9.tar.xz
master-sync-shared-d05168ce96faaad75d79671e1cdf2eaccb884ed9.zip
Undo refactoring.. Classes are working again. Could not find the mistake :/
Diffstat (limited to 'src/main/java/org/openslx/filetransfer/Downloader.java')
-rw-r--r--src/main/java/org/openslx/filetransfer/Downloader.java322
1 files changed, 293 insertions, 29 deletions
diff --git a/src/main/java/org/openslx/filetransfer/Downloader.java b/src/main/java/org/openslx/filetransfer/Downloader.java
index d9e41a5..c860f5e 100644
--- a/src/main/java/org/openslx/filetransfer/Downloader.java
+++ b/src/main/java/org/openslx/filetransfer/Downloader.java
@@ -1,46 +1,74 @@
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 extends Transfer
+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 String outputFilename = null;
+ private String ERROR = null;
- private static final Logger log = Logger.getLogger( Downloader.class );
+ private static Logger log = Logger.getLogger( Downloader.class );
/***********************************************************************/
/**
- * Actively initiate a connection to a remote peer for downloading.
+ * Constructor for satellite downloader.
+ * Tries to connect to specific ip and port and sending type of action.
*
- * @param host Host name or address to connect to
- * @param port Port to connect to
- * @throws IOException
+ * @param ip
+ * @param port
*/
- public Downloader( String host, int port, SSLContext context ) throws IOException
+ public Downloader( String ip, int port, SSLContext context )
{
- super( host, port, context, log );
- dataToServer.writeByte( 'D' );
+ 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();
+ }
}
/***********************************************************************/
/**
- * Constructor used by Listener to create an incoming download connection.
+ * Constructor for master downloader.
+ * Given parameter is the socket over which the transfer is going.
*
- * @param socket established connection to peer which requested an upload.
- * @throws IOException
+ * @param socket
*/
- protected Downloader( SSLSocket socket ) throws IOException
+ public Downloader( SSLSocket socket )
{
- super( socket, log );
+ try {
+ satelliteSocket = socket;
+ dataToServer = new DataOutputStream( satelliteSocket.getOutputStream() );
+ dataFromServer = new DataInputStream( satelliteSocket.getInputStream() );
+ } catch ( IOException e ) {
+ e.printStackTrace();
+ }
}
/***********************************************************************/
@@ -67,16 +95,211 @@ public class Downloader extends Transfer
/***********************************************************************/
/**
- * Method to request a byte range within the file to download. This
- * method is called by the party that initiated the connection.
+ * 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.
*
- * @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 boolean requestRange( long startOffset, long endOffset )
+ public String getToken()
{
- return super.sendRange( startOffset, 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;
}
/***********************************************************************/
@@ -84,20 +307,21 @@ public class Downloader extends Transfer
* Method for reading Binary. Reading the current Range of incoming binary.
*
*/
- public boolean receiveBinary()
+ public Boolean readBinary()
{
RandomAccessFile file = null;
try {
- int chunkLength = getDiffOfRange();
- byte[] incoming = new byte[ 64000 ];
+ int length = getDiffOfRange();
+ byte[] incoming = new byte[ 4000 ];
int hasRead = 0;
file = new RandomAccessFile( new File( outputFilename ), "rw" );
file.seek( getStartOfRange() );
- while ( hasRead < chunkLength ) {
- int ret = dataFromServer.read( incoming, 0, Math.min( chunkLength - hasRead, incoming.length ) );
+ while ( hasRead < length ) {
+ int ret = dataFromServer.read( incoming, 0, Math.min( length - hasRead, incoming.length ) );
// log.info("hasRead: " + hasRead + " length: " + length + " ret: " + ret);
if ( ret == -1 ) {
- log.info( "Error occured while receiving payload." );
+ log.info( "Error occured in Downloader.readBinary(),"
+ + " while reading binary." );
return false;
}
hasRead += ret;
@@ -109,7 +333,6 @@ public class Downloader extends Transfer
sendErrorCode( "timeout" );
log.info( "Socket timeout occured ... close connection." );
this.close();
- return false;
} catch ( Exception e ) {
e.printStackTrace();
log.info( "Reading RANGE " + getStartOfRange() + ":" + getEndOfRange()
@@ -124,8 +347,49 @@ public class Downloader extends Transfer
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();
+ }
+ }
}