How to write a simple Ping method in Cocoa/Objective-C

38,470

Solution 1

The code below seems to be working synchronously:

const char *hostName = [@"stackoverflow.com"
                        cStringUsingEncoding:NSASCIIStringEncoding];
SCNetworkConnectionFlags flags = 0;
if (SCNetworkCheckReachabilityByName(hostName, &flags) && flags > 0) {
  NSLog(@"Host is reachable: %d", flags);
}
else {
  NSLog(@"Host is unreachable");
}

Note: SystemConfiguration.framework is required

Solution 2

NOTE- I would recommend Chris' solution below which actually answers the question asked, directly. This post from 12 years ago was in response to the original authors upvoted answer, to which I had a better solution. As the author upvoted the answer above that used Reachability, I assumed that he was in fact more interested in reachability than actually in sending a ping, hence my answer. Please consider this before downvoting this answer.

StreamSCNetworkCheckReachabilityByName is deprecated and NOT available for the iPhone. Note: SystemConfiguration.framework is required

bool success = false;
const char *host_name = [@"stackoverflow.com" 
                         cStringUsingEncoding:NSASCIIStringEncoding];

SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL,
                                                                        host_name);
SCNetworkReachabilityFlags flags;
success = SCNetworkReachabilityGetFlags(reachability, &flags);

//prevents memory leak per Carlos Guzman's comment
CFRelease(reachability);

bool isAvailable = success && (flags & kSCNetworkFlagsReachable) && 
                             !(flags & kSCNetworkFlagsConnectionRequired);
if (isAvailable) {
    NSLog(@"Host is reachable: %d", flags);
}else{
    NSLog(@"Host is unreachable");
}

Solution 3

I had this same problem, and ended up writing a simple wrapper around SimplePing to achieve this, wrote a blog about it and there's some code on github, hopefully will help someone here:

http://splinter.com.au/how-to-ping-a-server-in-objective-c-iphone

Solution 4

You are not missing anything -- "Reachability" doesn't actually test that the target domain is in fact reachable, it only assesses if there is a pathway out of the machine by which the target domain is potentially reachable. So long as you have some outbound connection (e.g., an active wirless or wired connection), and a routing configuration that leads to the target, then the site is "reachable" as far as SCNetworkReachability is concerned.

Solution 5

Pinging on the iPhone works a bit different than on other platforms, due to the fact that you don't have root access. See this sample code from Apple.

Share:
38,470
Richard Stelling
Author by

Richard Stelling

Tech geek and hopelessly optimistic about my pessimistic outlook. http://www.richardstelling.com http://twitter.com/rjstelling http://careers.stackoverflow.com/rjstelling SOreadytohelp

Updated on July 09, 2022

Comments

  • Richard Stelling
    Richard Stelling almost 2 years

    I need to write a simple ping method in Cocoa/Objective-C. It also needs to work on the iPhone.

    I found an example that uses icmp, will this work on the iPhone?

    I'm leaning towards a solution using NSNetServices, is this a good idea?

    The method only needs to ping a few times and return the average and -1 if the host is down or unreachable.

  • William Remacle
    William Remacle over 13 years
    Unfortunately, SCNetworkCheckReachabilityByName is now deprecated.
  • bestsss
    bestsss over 12 years
    8 votes and +bounty for code that totally doesn't do what question was about, i.e. ping/traceroute but it's a DNS lookup, basically.
  • ahmet alp balkan
    ahmet alp balkan almost 12 years
    This file is removed from all around apple developer library.
  • Bill Patterson
    Bill Patterson about 11 years
    Upvote for a solution that actually answers the question (vs all this useless Reachability stuff which people seem to like but which is totally not addressing the question asked!). Thank you!
  • user623396
    user623396 over 9 years
    Yes, this is the actual answer.
  • Adro
    Adro almost 9 years
    The code is not only deprecated but also looking up the DNS
  • Vadim
    Vadim almost 9 years
    “You cannot delete this accepted answer”. Sorry guys! 😃
  • Carlos Guzman
    Carlos Guzman over 7 years
    Hi. Excelent code and helpful, but only one thing. You require add the code CFRelease(reachability) after call SCNetworkReachabilityGetFlags to release reachability variable (to prevent memory leaks) as is mentioned in documentation
  • adib
    adib over 7 years
    SCNetworkReachability is a poor indicator of whether a host is online. On a LAN situation, reachability seems to always returns that the host is reachable whenever there is a WiFi connection although it's really an invalid host name.
  • adib
    adib over 7 years
    SCNetworkReachabilityGetFlags is a poor substitute of ping – if the device is connected to a network, kSCNetworkFlagsReachable will be set and kSCNetworkFlagsConnectionRequired will be unset even though the target host is offline.
  • Gene Myers
    Gene Myers over 7 years
    I was improving on the accepted answer. I don't debate that SCNetworkReachabilityGetFlags is a poor substitute for 'ping', but if you are just trying to determine reachability, as was rjstelling objective, then this is a fine solution. If you need to monitor latency or provide a heartbeat, then a 'ping' solution is arguably better.