Используйте CFWriteStream для передачи файла в сокет - PullRequest
1 голос
/ 24 июня 2011

Я создал небольшое приложение, которое должно отправлять строку NSString на мой сервер.У меня там работает приложение, которое прослушивает внешний порт и действует как мусорная корзина: оно сохраняет все данные, которые поступают оттуда.

Созданное мною приложение iPhone использует это:

-(IBAction)pressButton:(id)sender {
    NSString *iHostname = [NSString stringWithFormat:@"xxx.xxx.xxx.xxx"];
    NSString *iPort = [NSString stringWithFormat:@"9100"];

    CFWriteStreamRef writeStream;
    static const CFOptionFlags kWriteNetworkEvents = kCFStreamEventEndEncountered |
    kCFStreamEventErrorOccurred |
    kCFStreamEventCanAcceptBytes |
    kCFStreamEventOpenCompleted |
    kCFStreamEventNone;
    CFStreamClientContext ctxt = {0,(void*)NULL,NULL,NULL,NULL};
    CFHostRef hostRef = CFHostCreateWithName(kCFAllocatorDefault,(CFStringRef)iHostname);

    CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, hostRef, [iPort intValue],
                                         NULL, &writeStream);

    CFWriteStreamSetClient(writeStream, kWriteNetworkEvents, WriteStreamClientCallBack, &ctxt);
    CFWriteStreamScheduleWithRunLoop(writeStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

Итак, я вызываю метод runloop:

static void WriteStreamClientCallBack( CFWriteStreamRef stream, CFStreamEventType type, void *clientCallBackInfo ) {
    NSLog(@"%lu", type);
    switch (type)
    {
        case kCFStreamEventEndEncountered:
        {
            NSLog(@"Closing");
            CFWriteStreamClose(stream);
            break;
        }
        case kCFStreamEventErrorOccurred:
        {
            NSLog(@"Crap, error!");
            break;
        }
        case kCFStreamEventCanAcceptBytes:
        {
            NSLog(@"Stream can accept more bytes");
            NSString *reqStr = [NSString stringWithFormat: @"ConReq"];
            const UInt8 *rawstring = (const UInt8 *)[reqStr UTF8String];
            CFWriteStreamWrite(stream, rawstring, strlen((char *)rawstring));
        }
        case kCFStreamEventNone:
        {
            NSLog(@"Nothing is happening");
            break;
        }
        case kCFStreamEventOpenCompleted:
        {
            NSLog(@"Opened stream!");
            break;
        }
    }
}

Здесь возникает проблема: когда я нажимаю кнопку, она остается там зацикленной.Регистрация показывает, что дело kCFStreamEventCanAcceptBytes просто продолжает вызываться.Действительно, когда я принудительно закрываю программу, сервер получает файл с большим количеством ConReq.Что мне с этим делать или что я делаю не так?

PS.Я получил код от здесь .

1 Ответ

1 голос
/ 24 июня 2011

Событие «принять» указывает на то, что если у вас есть дополнительные данные для отправки, вы можете отправить (некоторые из них) без блокировки. Ваша проблема в том, что вы не отслеживаете, сколько данных вы отправили, сколько данных осталось отправить и может ли сокет в настоящее время принимать данные. Вместо этого каждый раз, когда есть место для отправки большего количества данных, вы каждый раз отправляете одни и те же данные. Это не так много данных, поэтому вы должны ожидать, что вы быстро увидите много событий "готов к большему количеству данных".

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