David Hoerl
David Hoerl

Reputation: 41652

Why does CFStreamCreatePairWithSocketToCFHost fail when CFStreamCreatePairWithSocketToHost succeeds

On iOS6.1, the following code should do the very same thing, but when I forgot to write addr.sin_len = sizeof(adde) the first block failed. The original error was:

GOT EVENT FROM INPUT Event: 8
ERR: Error Domain=NSPOSIXErrorDomain Code=12 "The operation couldn’t be completed. Cannot allocate memory"

After adding in the missing line to set the struct size, the first block worked just as the second. Probably other developers will see that error message and trip on this post.

The code:

    CFReadStreamRef readStream = NULL;
    CFWriteStreamRef writeStream = NULL;

#if 1 // LONG WAY
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_len        = sizeof(addr);  // ORIGINALLY WAS MISSING
    addr.sin_family     = AF_INET;
    addr.sin_port       = htons(5566);
    int ret = inet_pton(AF_INET, "192.168.1.2", &(addr.sin_addr.s_addr)); // IPv4
    assert(ret == 1);

    NSLog(@"CONNECT");
    CFDataRef address = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)&addr, sizeof(addr));
    assert(address);

    CFHostRef macMini = CFHostCreateWithAddress(kCFAllocatorDefault, address);
    CFRelease(address);
    assert(macMini);

    // (tried, makes not difference) CFHostScheduleWithRunLoop (macMini, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

    CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, macMini, 5566, &readStream, &writeStream);
    CFRelease(macMini);
#else // SHORT WAY
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, CFSTR("192.168.1.2"), 5566, &readStream, &writeStream);
#endif

    assert(readStream);
    assert(writeStream);

    iStream = CFBridgingRelease(readStream);
    oStream = CFBridgingRelease(writeStream);

    [iStream setDelegate:self];
    [iStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [iStream open];
    NSLog(@"ISTREAM %@ status=%d", iStream, [iStream streamStatus]);
    NSLog(@"ERR: %@", [iStream streamError]);

    [oStream setDelegate:self];
    [oStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [oStream open];
    NSLog(@"OSTREAM %@ status=%d", oStream, [oStream streamStatus]);
    NSLog(@"ERR: %@", [oStream streamError]);

Upvotes: 1

Views: 1203

Answers (1)

David Hoerl
David Hoerl

Reputation: 41652

Problem was that sin_len was not set. The nice thing about having both sets of code above, is that you can see how to accomplish the task either way.

Upvotes: 1

Related Questions