4

I am playing with GCDAsyncSocket (MRC / iOS5.1) for a while, especially with "large" files (5 - 10 mb). Unfortunately sometimes the read stream is never completed (e.g. it gets stuck) just a few bytes at the end of the stream; the didReadPartialDataOfLength: stops giving me information and the didReadData is not fired at all.

Here's some of my code (for both writing / reading examples the connection between the host and client have been established)

WRITING

#define kHeadTag 0
#define kDataTag 1

typedef struct {
    NSUInteger size;
} head_t;

-(void)sendData:(NSData *)__data  {
    _sendData = [__data retain];

    head_t header;
    header.size = __data.length;
    [_socket writeData:[NSData dataWithBytes:&header
                                   length:sizeof(header)]
       withTimeout:-1
       tag:kHeadTag];
}

-(void)socket:(GCDAsyncSocket *)sock
       didWriteDataWithTag:(long)tag {
    if (tag == kHeadTag) {
        [sock writeData:_sendData withTimeout:-1 tag:kDataTag];
        [_sendData release];
        _sendData = nil;
    }
}

READING

-(void)socket:(GCDAsyncSocket *)sock
       didReadData:(NSData *)data
       withTag:(long)tag {
    switch (tag) {            
            // ------------------------------------- HEAD
        case kHeadTag:{
            head_t head;
            [data getBytes:&head length:sizeof(head)];
            _readHead = head;
            NSLog(@"Received header (total size = %i bytes)", head.size);
            [sock readDataToLength:head.size
                withTimeout:-1
                tag:kDataTag];
        }
            break;

            // ------------------------------------- BODY
        case kDataTag: {
             NSLog(@"Data received with %i bytes", data.length);
             [sock readDataToLength:sizeof(head_t) withTimeout:-1 tag:kHeadTag];
        }
            break;
    }
};

-(void)socket:(GCDAsyncSocket *)sock
       didReadPartialDataOfLength:(NSUInteger)partialLength
       tag:(long)tag {
    if (tag == kDataTag) {
        NSLog(@"Data read with %i bytes", partialLength);
    }
};

I hope this is enough code to see what I'm doing wrong or maybe this is a bad practice for writing/reading large chunks of data.

basvk
  • 4,437
  • 3
  • 29
  • 49

1 Answers1

0

I added
[self.partnerSocket writeData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0]; at the end of sendData: method, and it works fine for me. You just have to append separator chars at the end of the data. I can transfer around 48MB of file from one iDevice to other iDevice