Extended File Transfer sample (Cocoa)

This sample shows how the client can download files exposed by the server in chunks and with multiple threads.

Server Requirements

The Extended File Transfer server is required from Delphi or .NET sample set. In order to test this sample, please put some files into the shared folder on the server side.

Getting Started

Build and launch the ExtendedFileTransfer sample server, make sure the server's shared folder contains some files. Build and launch the sample. Correct the target URL in the text box (the server IP address or host name) to provide a valid target URL of the sample server. Click the Get Files button to retrieve the list of files available for download. Select one of the files, set the desired Chunk Size and Thread count values (the Chunk count value is calculated based on file size and selected chunk size). Then click the Download button and set the file name and location when asked.

Examine the code

The AppController class is responsible for the sample operations. There is also the auxiliary class to reflect the download thread state and to actually download the file chunk with the -(void)downloadPart:(id)delegate method:

ROBinMessage *msg = [[[ROBinMessage alloc] init] autorelease];
ROHTTPClientChannel *channel = [[[ROHTTPClientChannel alloc] initWithTargetUrl:TargetUrl] autorelease];
ExtendedFileTransferService_Proxy *serv = 
    [[[ExtendedFileTransferService_Proxy alloc] initWithMessage:msg channel:channel] autorelease];
    
[self logMessage:@"Receiving data" UsingDelegate:delegate];
NSData *data = [serv DownloadFilePart:FileName :ChunkNo :ChunkSize];
    
[self logMessage:@"Writing data to file" UsingDelegate:delegate];
@synchronized(FileStream)
{
    [FileStream seekToFileOffset:ChunkSize * (ChunkNo - 1)];
    [FileStream writeData:data];
}
[self logMessage:@"Chunk done" UsingDelegate:delegate];

Also examine the -(IBAction)downloadFile:(id)sender method to see how the download process is organized. The Cocoa queuing facility is used to perform background chunk download tasks.

for (int i = 1; i <= ChunkCount; i++) 
{
    DownloadThreadState *state = [DownloadThreadState alloc];
    [state initWithTargetUrl:TargetURL 
                    FileName:[selectedFile FileName]
                    FileStream:Stream 
                    ChunkSize:ChunkSize 
                    ChunkNo:i 
                    DownloadPath:path];
    NSInvocationOperation *op = [NSInvocationOperation alloc];
    [op initWithTarget:state selector:@selector(downloadPart:) object:self];
    [Queue addOperation:op];
    [op release];
}
        
[QueueThread initWithTarget:self selector:@selector(processQueue:) object:nil];
[QueueThread start];