Alkimake
Alkimake

Reputation: 1797

NSInputStream read returns unsigned integer maximum value when bytes available

I try to read and write data from/to Socket with NSStream. Here is my code for connect :

- (void)connect
{
  [NSStream getStreamsToHostNamed:APIC_HOST_ADDR 
                             port:APIC_HOST_PORT
                      inputStream:&inStream
                     outputStream:&outStream];
  [inStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
  [outStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

  inStream.delegate = self;
  outStream.delegate = self;

  if ([inStream streamStatus] == NSStreamStatusNotOpen)
    [inStream open];

  if ([outStream streamStatus] == NSStreamStatusNotOpen)
    [outStream open];

}

and for input stream i implement the delegate methods to recieve events

- (void)handleInputStreamEvent:(NSStreamEvent)eventCode
{
  switch (eventCode) {
    case NSStreamEventHasBytesAvailable:
    {
    int bytesRead;
    if (data == nil) {
      data = [[NSMutableData alloc] init];
    }
    uint8_t buf[1024];
    unsigned int len = 0;
    len = [inStream read:buf maxLength:1024];
    if(len>0) {
      @try {
        [data appendBytes:(const void *)buf length:len];
      }
      @catch (NSException *exception) {
        NSLog(@"Fail: %@", exception);
      }
      @finally {
        NSLog(@"Finally");
        bytesRead += len;
      }
    } else {
      NSLog(@"No Buffer");
    }  

    NSString *str = [[NSString alloc] initWithData:data 
                                          encoding:NSUTF8StringEncoding];
    NSLog(@"%@",str);
    [str release];
    [data release];        
    data = nil;
    } break;
    case NSStreamEventErrorOccurred:
    {
      NSError *theError = [inStream streamError];
      NSLog(@"Error reading stream! ,Error %i: %@",[theError code], [theError localizedDescription]);
      [self disconnect];
      [self connect];
    } break;
  }
}

[NSStream read:maxLength:] always returns maximum unsigned integer value. Eventually i get this error:

Fail: *** -[NSConcreteMutableData appendBytes:length:]: unable to allocate memory for length (4294967295)

Why does read mehod return this big value? Does it really read that much bytes? (I don't think so) :)

PS: Socket Stream server is ok. it reads and writes data to other clients also and there is no problem.

Upvotes: 3

Views: 2728

Answers (3)

leopardpan
leopardpan

Reputation: 56

If from CFReadStreamRead() method returns 1, means the request fails, you should do the processing of failure. CFReadStreamRead() method to read failure will return 1, with 4294967295-1 is the same block of memory, so the length was 4294967295.

Upvotes: 0

user2045184
user2045184

Reputation: 69

from the NSInputStream read:maxLength documentation:

Return Value A number indicating the outcome of the operation A positive number indicates the number of bytes read 0 indicates that the end of the buffer was reached A negative number means that the operation failed

so in case of end of stream your len is 0, in case of error it is -1 which explains the 4294967295 value on your unsigned int.

so use a signed int and check for negative values.

Upvotes: 3

Alkimake
Alkimake

Reputation: 1797

I resolved the problem. I was writing data without observing if has space available in output stream.

Upvotes: 3

Related Questions