Roshit
Roshit

Reputation: 1579

Sending files over Socket (iOS)

I created a Socket based Simple Chat app. The Post: Socket Based iPhone App helped me create this.

I now want to send/receive files over the socket. Please give me pointers as to how I can go about to achieve this.

Cheers, Roshit

EDIT:

Code used to connect to socket is :

NSString *aHostName = @"xx.xx.xx.xx";
NSInteger aPort = 1234;

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)aHostName, aPort, &readStream, &writeStream);

self.inputStream = (NSInputStream *)readStream;
self.outputStream = (NSOutputStream *)writeStream;

[self.inputStream setDelegate:self];
[self.outputStream setDelegate:self];

[self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[self.inputStream open];
[self.outputStream open];

Code used to send data is

NSData *aData = [[NSData alloc] initWithData:[iRequestAPI dataUsingEncoding:NSASCIIStringEncoding]];
[self.outputStream write:[aData bytes] maxLength:[aData length]];
[aData release];

where, iRequestAPI is the string that has to be sent.

Now when I try sending a file over socket, considering the fact I convert the File into NSData and use [self.outputStream write:[aData bytes] maxLength:[aData length]]; can there be a possibility that the entire file is not sent due to connection bandwidth. If the entire file is not sent, how to ensure the rest of it is sent.

Is this the right approach to send a file over socket. Please suggest..

Upvotes: 2

Views: 6102

Answers (2)

user1511182
user1511182

Reputation: 21

If your NSData is big enough you need to cut it into pieces.You'll need bytes to transfer them .For example:

NSData *newData = UIImagePNGRepresentation([UIImage imageNamed:@"Default.png"]);
    int index = 0;
    int totalLen = [newData length];
    uint8_t buffer[1024];
    uint8_t *readBytes = (uint8_t *)[newData bytes];

    while (index < totalLen) {
        if ([outputStream hasSpaceAvailable]) {
            int indexLen =  (1024>(totalLen-index))?(totalLen-index):1024;

            (void)memcpy(buffer, readBytes, indexLen);

            int written = [outputStream write:buffer maxLength:indexLen];

            if (written < 0) {
                break;
            }

            index += written;

            readBytes += written;
        }
    }

Upvotes: 2

Caleb
Caleb

Reputation: 124997

Files contain data. Network connections (socket or otherwise) transfer data. You could just open the file, read the data, and start writing that very same data to your socket. However...

You probably want to transfer the file within the context of the chat session. So, you're going to want to delimit the file somehow, so that the receiving end of the connection realizes that the data coming across is a file. And you'll probably want to transfer some metadata for the file, such as name, size, etc.

Exactly how you do all that is entirely up to you. You're writing the code at both ends of the connection, so if you come up with a plan and implement it properly, you should be able to make it work. One approach would use some magic string, like +++++++++++++ to delimit the start of the file information. If you specify the number of bytes, then you can write that many bytes to the connection and expect the other side to read that many bytes. Another way to do it would be to convert your entire data stream to include meta-information. For example, you could use an XML-based format.

It's really up to you.

Upvotes: 1

Related Questions