login about faq

Hi,

I've a requirement to be sending large files over socket connection in iOS. From what I understand I will have to do the chunking myself.

  • What's the preferred method of letting the other device know how much data to expect?
  • How do I deal with and respond to errors?
  • Can I use the socket conneciton to ack success/failiure?

Here is some sample code that will successfully transfer, in chunks, a huge file. First set up a socket connection and send over the size of the file in string form. Then send chunks over.

CkoFileAccess *fac = [[CkoFileAccess alloc] init];
if (![fac OpenForRead:filePath]) {
    NSLog(@"Open for read error\n%@", fac.FileOpenErrorMsg);
}

NSInteger chunkSize = 1048576;

unsigned long long completedBytes = 0;
unsigned long long fileSize = [[fac FileSize:filePath] longLongValue];

NSString *sizeString = [NSString stringWithFormat:@"%lli-EOM-", fileSize];
success = [socket SendString:sizeString];
if (success != YES) {
    NSLog(@"err 3: %@", socket.LastErrorText);
    return;
}

while (completedBytes < fileSize) {

    NSInteger chunk = (completedBytes + chunkSize < fileSize) ? chunkSize : fileSize - completedBytes;

    NSData *data = [fac FileRead:[NSNumber numberWithInteger:chunk]];

    if (![socket SendBytes:data numBytes:[NSNumber numberWithInteger:chunk]]) {
        NSLog(@"Err - %@", [socket LastErrorText]);
    }

    completedBytes += chunk;
}

On the receiving end I will listen for the size string. Let the length in bytes and keep a byte count as well so I know how many chunks to expect and how many bytes in each chunk.

// get file size
NSString *sizeString = [clientSock ReceiveUntilMatch: @"-EOM-"];
if (receivedMsg == nil ) {
    NSLog(@"err 7: %@", clientSock.LastErrorText);
    return;
}
sizeString = [sizeString stringByReplacingOccurrencesOfString:@"-EOM-" withString:@""];
unsigned long long fileSize = [sizeString longLongValue];

CkoFileAccess *fac = [[CkoFileAccess alloc] init];

if (![fac OpenForWrite:filePath]) {
    NSLog(@"Faield to open for write %@", [fac FileOpenErrorMsg]);
}

unsigned long long receivedBytes = 0;

NSInteger chunkSize = 1048576;

while (receivedBytes < fileSize) {

    NSInteger chunk = (receivedBytes + chunkSize < fileSize) ? chunkSize : fileSize - receivedBytes;

    NSData *data = [clientSock ReceiveBytesN:[NSNumber numberWithInteger:chunk]];

    receivedBytes += chunk;

    if (![fac FileWrite:data]) {
        NSLog(@"failed to write");
    }
}

[fac FileClose];

I can't help but feel I'm doing this in a bit of a roundabout way? Can I make this implementation more efficient? I'm also looking to improve the (non-existent) error handling in the above

thanks!

asked Feb 06 '13 at 09:51

Dan's gravatar image

Dan
1222


Dan,

Your implementation is exactly what I would do if faced with the same task. It's not roundabout at all. In fact, most protocols work this way: IMAP, SMTP, POP3, HTTP, FTP, etc. In different formats, the amount of forthcoming data to be sent is first provided to the server in a separate message so that the server knows how much data is expected.

As far as responding to errors goes -- if a read or write on either side fails, maybe because the other side closes its connection, or stops read/writing prematurely, or because of an external network connectivity problem (i.e. ethernet cable unplugged), then the side that discovers the error should close the connection and report it in any way it sees fit.

link

answered Feb 06 '13 at 18:07

chilkat's gravatar image

chilkat ♦♦
11.8k316358420

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or __italic__
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×4
×3
×1

Asked: Feb 06 '13 at 09:51

Seen: 1,644 times

Last updated: Feb 06 '13 at 18:07

powered by OSQA