CFStream IOS Socket communication

2.6k Views Asked by At

how can i clear an CFStream buffer? Everytime i read from socket there is still data from an old request, i mean complete response to an old request not just a fragment of it.

Am i missing something ?

This is a function i use to initialize the connection:

-(void)openSocketConnection:(UInt32)port: (NSString *)host
{
  NSString *hoststring  = [[NSString alloc] initWithString:host];
  CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,(__bridge CFStringRef)hoststring ,
port,&_nnet_readStream,&_nnet_writeStream);

CFWriteStreamCanAcceptBytes(_nnet_writeStream);

CFWriteStreamSetProperty(_nnet_writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);

CFReadStreamSetProperty(_nnet_readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);

    if(!CFWriteStreamOpen(_nnet_writeStream)) {
        NSLog(@"Error Opening Write Socket");
    }
    if(!CFReadStreamOpen(_nnet_readStream)) {
        NSLog(@"Error Opening Write Socket");
    }

}

This is a function i use to read data from socket:

BOOL done = NO;
NSMutableString* result = [NSMutableString string];
while (!done) 
{
        if (CFReadStreamHasBytesAvailable(_nnet_readStream)) 
        {
            UInt8 buf[1024];
            CFIndex bytesRead = CFReadStreamRead(_nnet_readStream, buf, 1024);
            if (bytesRead < 0) 
            {
                CFStreamError error = CFReadStreamGetError(_nnet_readStream);
                NSLog(@"%@",error);
            } else if (bytesRead == 0) 
            {
                if (CFReadStreamGetStatus(_nnet_readStream) == kCFStreamStatusAtEnd) 
                {
                    done = YES;
                }
            } else 
            {
                [result appendString:[[NSString alloc] initWithBytes:buf length:bytesRead encoding:NSUTF8StringEncoding]];
            }
        } else 
        {
            done = YES;
        }
}   
1

There are 1 best solutions below

3
On

You seem to assume that when you get data from the host on the other end it will always be available all in one go.

I don't know what the underlying protocol is, but in general it's entirely possible that the remote end will try and send 1600 bytes and that you'll get 1500 bytes but then have to wait a few milliseconds (or even seconds) for the next 100 bytes. Meanwhile CFReadStreamHasBytesAvailable would return false and so your code would set your done flag even though you haven't read all the data the server sent.