1

CFStream を使用して単純な HTTP 通信を機能させようとしていますが、以下のコードを使用すると、無効な URL (www.yahoo.com) を指定しても接続が成功します。

誰かがこのコードのどこが悪いのか教えてもらえますか? CFReadStreamOpen() の呼び出しが失敗することを期待していますが、URL が正しくなくても成功しています。

ARCで動作するHTTP(NSURLを使用しない)を行う単純なCFNetworkの例を見つけることができませんでした。そのようなサンプルコードを知っている人がいたら教えてください。

- (void) test
{

    CFStringRef m_host = CFStringCreateWithCString(NULL, "wwwww.yahoo.com", kCFStringEncodingASCII);

    int m_port = 80;
    CFHostRef host;

    NSLog(@"Attempting to (re)connect to %@:%d", m_host, m_port);

    {

        CFReadStreamRef     m_in = NULL;
        CFWriteStreamRef    m_out = NULL;

        host = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)m_host);
        if (!host)
        {
            NSLog(@"Error resolving host %@", m_host);
        }

        CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, host , m_port, &m_in, &m_out);
        CFRelease(host);

        CFStreamClientContext context = {0, nil,nil,nil,nil}; 


        if (CFReadStreamSetClient(m_in, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, networkReadEvent, &context))
        {
            CFReadStreamScheduleWithRunLoop(m_in, CFRunLoopGetCurrent(),kCFRunLoopCommonModes);
        }

        if (CFWriteStreamSetClient(m_out, kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, networkWriteEvent, &context))
        {
            CFWriteStreamScheduleWithRunLoop(m_out, CFRunLoopGe   tCurrent(),kCFRunLoopCommonModes);
        }        

        BOOL success = CFReadStreamOpen(m_in);
        CFErrorRef error = CFReadStreamCopyError(m_in);
        if (!success || (error && CFErrorGetCode(error) != 0))
        {
            NSLog(@"Connect error %s : %ld", CFErrorGetDomain(error), CFErrorGetCode(error));
            [NSThread sleepForTimeInterval:5.0];
        }

        success = CFWriteStreamOpen(m_out);
        error = CFReadStreamCopyError(m_in);
        if (!success || (error && CFErrorGetCode(error) != 0))
        {
            NSLog(@"Connect error %s : %d", CFErrorGetDomain(error), CFErrorGetCode(error));
            [NSThread sleepForTimeInterval:5.0];
        }
        else 
        {
            NSLog(@"Connected");
        }

    }
}
4

1 に答える 1

0

あなたのような非同期コードの場合、デリゲートを設定してそこでエラーをキャッチする必要があります。http://iphonedevsdk.com/forum/iphone-sdk-development/17542-cfstream-catch-error-in-connection.htmlをチェックしてください。

Apple Developer サイトによると、「ストリームがブロックせずにバックグラウンドで開くことができる場合、この関数は常に true を返します。」. つまり、ストリームを開くリクエストは別のスレッドで送信されるため、関数を呼び出すと true が返され、バックグラウンド スレッドで接続プロセスが開始されます。バックグラウンド スレッドがストリームのオープンを完了するまで、それぞれのストリームのすべての読み取り/書き込み呼び出しがブロックされます。「CFReadStreamOpen(m_in);」にブレークポイントを設定すると、これを確認できます。その1行が実行された後に何が起こるかを見てください。これがあなたの質問に答えることを願っています。

于 2014-10-24T05:48:13.603 に答える