summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/filetransfer/Downloader.java
blob: 69461735ed9d07b084073a22b1ce7e52087a84f7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package org.openslx.filetransfer;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.SocketTimeoutException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;

import org.apache.log4j.Logger;

public class Downloader extends Transfer
{
	// Some instance variables.
	private String outputFilename = null;

	private static final Logger log = Logger.getLogger( Downloader.class );

	/***********************************************************************/
	/**
	 * Actively initiate a connection to a remote peer for downloading.
	 * 
	 * @param host Host name or address to connect to
	 * @param port Port to connect to
	 * @throws IOException
	 */
	public Downloader( String host, int port, SSLContext context ) throws IOException
	{
		super( host, port, context, log );
		dataToServer.writeByte( 'D' );
	}

	/***********************************************************************/
	/**
	 * Constructor used by Listener to create an incoming download connection.
	 * 
	 * @param socket established connection to peer which requested an upload.
	 * @throws IOException 
	 */
	protected Downloader( SSLSocket socket ) throws IOException
	{
		super( socket, log );
	}

	/***********************************************************************/
	/**
	 * Method for setting outputFilename.
	 * 
	 * @param filename
	 */
	public void setOutputFilename( String filename )
	{
		outputFilename = filename;
	}

	/***********************************************************************/
	/**
	 * Method for getting outputFilename.
	 * 
	 * @return outputFilename
	 */
	public String getOutputFilename()
	{
		return outputFilename;
	}

	/***********************************************************************/
	/**
	 * 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 boolean requestRange( long startOffset, long endOffset )
	{
		return super.sendRange( startOffset, endOffset );
	}

	/***********************************************************************/
	/**
	 * Method for reading Binary. Reading the current Range of incoming binary.
	 * 
	 */
	public boolean receiveBinary()
	{
		RandomAccessFile file = null;
		try {
			int chunkLength = getDiffOfRange();
			byte[] incoming = new byte[ 64000 ];
			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 ) );
				// log.info("hasRead: " + hasRead + " length: " + length + " ret: " + ret); 
				if ( ret == -1 ) {
					log.info( "Error occured while receiving payload." );
					return false;
				}
				hasRead += ret;
				file.write( incoming, 0, ret );

			}
		} catch ( SocketTimeoutException ste ) {
			ste.printStackTrace();
			sendErrorCode( "timeout" );
			this.close( "Socket timeout occured ... close connection." );
			return false;
		} catch ( Exception e ) {
			e.printStackTrace();
			this.close( "Reading RANGE " + getStartOfRange() + ":" + getEndOfRange()
					+ " of file from socket failed..." );
			return false;
		} finally {
			if ( file != null ) {
				try {
					file.close();
				} catch ( IOException e ) {
					e.printStackTrace();
				}
			}
			RANGE = null; // Reset range for next iteration
		}
		return true;
	}
}