Pinging a Machine

Problem

You want to check whether a particular machine or domain name can be reached from your computer.

Solution

Use Rubys standard ping library. Its single method, Ping.pingecho, TRies to get some machine on the network to respond to its entreaties. It takes either a domain name or an IP address, and returns true if it gets a response.

require ping ping.pingecho(oreilly.com) # => true # timeout of 10 seconds instead of the default 5 seconds Ping.pingecho(127.0.0.1, 10) # => true # ping port 80 instead of the default echo port Ping.pingecho(slashdot.org, 5, 80) # => true Ping.pingecho( o.such.domain) # => false Ping.pingecho(222.222.222.222) # => false

Discussion

Ping.pingecho performs a TCP echo: it tries to make a TCP connection to the given machine, and if the machine responds (even if to refuse the connection) it means the machine was reachable.

This is not the ICMP echo of the Unix ping command, but the difference almost never matters. If you absolutely need an ICMP echo, you can invoke ping with a system call and check the return value:

system(ping -c1 www.oreilly.com) # 64 bytes from 208.201.239.36: icmp_seq=0 ttl=42 time=27.2 ms # # --- www.oreilly.com ping statistics -- # 1 packets transmitted, 1 packets received, 0% packet loss # round-trip min/avg/max = 27.2/27.2/27.2 ms # => true

If the domain has a DNS entry but can be reached, Ping::pingecho may raise a Timeout::Error instead of returning false.

Some very popular or very paranoid domains, such as microsoft.com, don respond to incoming ping requests. However, you can usually access the web server or some other service on the domain. You can see whether such a domain is reachable by using one of Rubys other libraries:

ping.pingecho(microsoft.com) # => false require et/http Net::HTTP.start(microsoft.com) { success! } # => "success!" Net::HTTP.start( o.such.domain) { "success!" } # SocketError: getaddrinfo: Name or service not known

Категории