Асинхронный ввод-вывод с CFReadStream - PullRequest
1 голос
/ 27 июля 2010

Это братский вопрос Асинхронный ввод-вывод с CFWriteStream . Я использую CFReadStreamScheduleWithRunLoop и CFReadSteamRead для выполнения асинхронного ввода-вывода. Как мы можем безопасно получить всю дату с блокировкой?

Допустим, фактический размер сообщения был 1200 (но мы не знаем), а размер моего буфера чтения был 1024. Вызов CFReadStreamRead извлечет до 1024 байтов данных, но так как Чтобы узнать размер сообщения, мы должны повторно вызывать CFReadStreamRead. Проблема в том, что, поскольку мы не знаем, сколько данных получило сокет потока, CFReadStreamRead может заблокировать второй вызов. Как мы можем избежать этой проблемы?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 05 августа 2010

Звоните еще раз CFReadStreamHasBytesAvailable() в своем потоке, чтобы увидеть, все еще безопасно ли читать с него (или если единственный способ узнать это - попробовать).

0 голосов
/ 07 марта 2011

Я добавил пример кода, который сделал работу за меня.Он использует CFReadStreamHasBytesAvailable ().Важно проверить состояние потока, иначе вы можете оказаться в бесконечном цикле.Мой пример также включает в себя обработку тайм-аута.

NSMutableData* bodyData = [NSMutableData dataWithCapacity:kHTTPReadStreamBufferSize];
    NSDate* startTimeStamp = [NSDate date];

    while (TRUE) {
        if (CFReadStreamHasBytesAvailable(httpReadStream)) {
            startTimeStamp = [NSDate date];
            UInt8* streambuffer = malloc(kHTTPReadStreamBufferSize);
            int readBytes = CFReadStreamRead (httpReadStream,streambuffer,kHTTPReadStreamBufferSize);
            NSLog(@"Read: %d",readBytes);
            [bodyData appendBytes:streambuffer length:readBytes];
            free(streambuffer);
        }

        if (CFReadStreamGetStatus(httpReadStream) == kCFStreamStatusError) {
            *error = (NSError*)CFReadStreamCopyError (httpReadStream);
            if ([*error code] == 61) {
                NSLog(@"Error occured: %d",[*error code]);
                // connection refused
                [PlusError errorForDomainWithCode:kPlusHostUnreachable errorDescription:NSLocalizedString(@"kPlusHostUnreachable",@"")
                                  underlyingError:nil url:nil toError:error];

            }
            *responseHeader = nil;
            *bodyContent = nil;
            break;          
        }

        if (CFReadStreamGetStatus(httpReadStream) == kCFStreamStatusAtEnd) {
            NSLog(@"Stream reached end!");
            *responseHeader = (CFHTTPMessageRef)CFReadStreamCopyProperty(httpReadStream, kCFStreamPropertyHTTPResponseHeader);      
            *error = nil;
            break;
        }

        // timeout management
        NSTimeInterval timeInterval = [startTimeStamp timeIntervalSinceNow]*-1;
        if (timeInterval >= kHTTPReadTimeOutTimeInSeconds) {
            [PlusError errorForDomainWithCode:kPlusResourceLoadingError errorDescription:NSLocalizedString(@"kPlusResourceLoadingError",@"") 
                              underlyingError:nil url:nil toError:error];

            break;
        }   
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...