0

I'm trying to check if an address and Port are available. For that I follow the different steps in this post (iphone) reachability test for specific ip/port? and my code :

BOOL hasLeadingNumberInString(NSString* s) {
    if (s)
        return [s length] && isnumber([s characterAtIndex:0]);
    else
        return NO;
}

-(BOOL)networkConnected: (NSString *)ipAdress Port:(int)port {
    SCNetworkReachabilityFlags  flags = 0;
    SCNetworkReachabilityRef    netReachability;
    BOOL                        retrievedFlags = NO;

    // added the "if" and first part of if statement
    //
    if (hasLeadingNumberInString(ipAdress)) {
        struct sockaddr_in the_addr;
        memset((void *)&the_addr, 0, sizeof(the_addr));
        the_addr.sin_family = AF_INET;
        the_addr.sin_port = htons(port);
        const char* server_addr = [ipAdress UTF8String];
        unsigned long ip_addr = inet_addr(server_addr);
        the_addr.sin_addr.s_addr = ip_addr;
        netReachability =    SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (struct sockaddr*)&the_addr);
    } else {
        netReachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [ipAdress UTF8String]);
    }
    if (netReachability) {
        retrievedFlags = SCNetworkReachabilityGetFlags(netReachability, &flags);
        CFRelease(netReachability);
    }
    if (!retrievedFlags || !flags) {
        return NO;
    }
    return YES;
}

But I always have NO even if couple address/port exist. What I'm doing wrong??

EDIT LOG:

netReachability is NIL
Community
  • 1
  • 1
Franky
  • 902
  • 2
  • 11
  • 28

2 Answers2

3

the_addr.sin_len = sizeof(the_addr);

You forgot to set this part of the struct. Without it, it will be interpreted as zero-length (invalid). If you set it, your SCNetworkReachabilityRef will no longer be NULL.

borrrden
  • 33,256
  • 8
  • 74
  • 109
2

The SCNetworkReachabilityCreateWithAddress() fails because you forgot to set

the_addr.sin_len = sizeof(the_addr);

If you add that it should work.

But note that the SCNetworkReachability functions only check if a packet can be routed to the destination. It does not verify if a host is actually listening at the given port.

Therefore, the port number is irrelevant, and you could just use

netReachability  = SCNetworkReachabilityCreateWithName(NULL, server_addr);

without all the struct sockaddr_in hassle.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Actually the entire server is really irrelevant. You could use any IP address you wanted (even invalid ones) and as long as you are connected to the Internet Reachability will be satisfied. – borrrden Jul 03 '13 at 09:51
  • Because this method does not give the expected result, what you propose me or suggest me to test whether a port and address are available? – Franky Jul 03 '13 at 10:01
  • @iPisix: The only way it to actually *connect* to that host/port. You can use the "low-level" `connect()` or perhaps higher level frameworks , see http://developer.apple.com/library/mac/#documentation/Networking/Conceptual/CFNetwork/Introduction/Introduction.html. – Martin R Jul 03 '13 at 10:04
  • I found solution with "SOCKET" – Franky Jul 04 '13 at 09:52