0

I have been doing a client-server communication for a while in iOS but I am here faced to an issue I have some troubles to understand.

I wrote two basic functions: one to send data to the server and the other to receive data from the server. Each one has a parameter called timeout which allows to make the current thread sleep and wake up every 0.25s until the timeout is reached:

-(ReturnCode) send : (NSData*)data :(int)timeOut
   {
    if(![self isConnectionOpened]) return KO;

    float timer = 0;

    while(![_outputStream hasSpaceAvailable])
    {
        [NSThread sleepForTimeInterval:0.25];
        timer+=0.25;
        if(timer == timeOut) break;
    }

    int ret = 0;
    if([_outputStream hasSpaceAvailable]){
        int lg = [data length];

        ret = [_outputStream write:[data bytes] maxLength:lg];

        if(ret == -1) return KO;
        else return OK;
    }

    return TIMEOUT;
}

- (ReturnCode) receive : (NSData**)data : (int)timeOut : (int)maxLength
{
    uint8_t buffer[maxLength];
    int len;
    NSMutableData* dataReceived = [[NSMutableData alloc] init];
    if(! [self isConnectionOpened]) return KO;

    float timer = 0;
    while(![_inputStream hasBytesAvailable])
    {
        [NSThread sleepForTimeInterval:0.25];
        timer+=0.25;
        if(timer == timeOut) break;
    }

    if(![_inputStream hasBytesAvailable]) return TIMEOUT;

    while ([_inputStream hasBytesAvailable]) {
        len = [_inputStream read:buffer maxLength:sizeof(buffer)];
        if (len > 0) {
            [dataReceived appendBytes:buffer length:len];
            *data = dataReceived;
            return OK;
        }
    }
    return KO;

}

With iPhone 4 + iOS6, everything is going fine. But under iOS7, for some fuzzy reasons, inputstream and outputstream are closing prematurely (NSStreamEventErrorOccurred raised). The fact is, if I put a breakpoint just before receiving data from server and make the code run, it works fine and reading/writing streams dont close wrongly.

So I think there is a synchronisation problem but I dont understand why... If anyone has ideas, pls help...

Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
Besoul
  • 35
  • 6

1 Answers1

1

I found where my issue was coming from.

Actually, be really careful on where are scheduled inputstream and outputstream. Indeed, I was told that Apple objects had to be executed on main thread, so I scheduled them this way:

dispatch_async(dispatch_get_main_queue(), ^ {
     [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
     [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

     [_inputStream open];
     [_outputStream open];
});

But actually, it seems better to schedule them on the current loop from the current thread, and not dispatching the schedule action on main thread:

     [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
     [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

     [_inputStream open];
     [_outputStream open];
Besoul
  • 35
  • 6