Local network pinging in python
Asked Answered
A

8

10

Does anyone know how to use python to ping a local host to see if it is active or not? We (my team and I) have already tried using

os.system("ping 192.168.1.*") 

But the response for destination unreachable is the same as the response for the host is up.

Thanks for your help.

Acanthus answered 6/10, 2011 at 17:55 Comment(0)
V
13

Use this ...

import os

hostname = "localhost" #example
response = os.system("ping -n 1 " + hostname)

#and then check the response...
if response == 0:
    print(hostname, 'is up!')
else:
    print(hostname, 'is down!')

If using this script on unix/Linux replace -n switch with -c !
Thats all :)

Votary answered 19/2, 2013 at 13:30 Comment(2)
in case i get reply 'Destination host unreachable.' its not working.Pinchcock
sure the Question could be better. but as he stated in the Description it does not work with "Destination host unreachable." - so your answer i wrong all the way.Stockyard
H
8

I've found that using os.system(...) leads to false positives (as the OP said, 'destination host unreachable' == 0).

As stated before, using subprocess.Popen works. For simplicity I recommend doing that followed by parsing the results. You can easily do this like:

if ('unreachable' in output):
        print("Offline")

Just check the various outputs you want to check from ping results. Make a 'this' in 'that' check for it.

Example:

import subprocess

hostname = "10.20.16.30"
output = subprocess.Popen(["ping.exe",hostname],stdout = subprocess.PIPE).communicate()[0]

print(output)

if ('unreachable' in output):
    print("Offline")
Hamann answered 9/8, 2013 at 21:34 Comment(1)
Be careful that parsing the output depends on the host OS language.Carpophore
G
6

The best way I could find to do this on Windows, if you don't want to be parsing the output is to use Popen like this:

num = 1
host = "192.168.0.2"
wait = 1000

ping = Popen("ping -n {} -w {} {}".format(num, wait, host),
             stdout=PIPE, stderr=PIPE)  ## if you don't want it to print it out
exit_code = ping.wait()

if exit_code != 0:
    print("Host offline.")
else:
    print("Host online.")  

This works as expected. The exit code gives no false positives. I've tested it in Python 2.7 and 3.4 on Windows 7 and Windows 10.

Gallican answered 25/5, 2018 at 6:59 Comment(0)
V
5

I've coded a little program a while back. It might not be the exact thing you are looking for, but you can always run a program on the host OS that opens up a socket on startup. Here is the ping program itself:

# Run this on the PC that want to check if other PC is online.
from socket import *

def pingit():                               # defining function for later use

    s = socket(AF_INET, SOCK_STREAM)         # Creates socket
    host = 'localhost' # Enter the IP of the workstation here 
    port = 80                # Select port which should be pinged

    try:
        s.connect((host, port))    # tries to connect to the host
    except ConnectionRefusedError: # if failed to connect
        print("Server offline")    # it prints that server is offline
        s.close()                  #closes socket, so it can be re-used
        pingit()                   # restarts whole process    

    while True:                    #If connected to host
        print("Connected!")        # prints message 
        s.close()                  # closes socket just in case
        exit()                     # exits program

pingit()                           #Starts off whole process

And here you have the program that can recieve the ping request:

# this runs on remote pc that is going to be checked
from socket import *

HOST = 'localhost'
PORT = 80
BUFSIZ = 1024
ADDR = (HOST, PORT)
serversock = socket(AF_INET, SOCK_STREAM)
serversock.bind(ADDR)
serversock.listen(2)

while 1:
    clientsock, addr = serversock.accept()
    serversock.close()
    exit()

To run a program without actually showing it, just save the file as .pyw instead of .py. It makes it invisible until user checks running processes.

Hope it helped you

Vilify answered 1/3, 2013 at 14:34 Comment(1)
Sorry - but the question was for pinging the server, which is a different scenario. The connect only makes sense once you know that the server exists and is alive!Ammonal
U
2

For simplicity, I use self-made functions based on socket.

def checkHostPort(HOSTNAME, PORT):
    """
        check if host is reachable
    """
    result = False
    try:
        destIp  =  socket.gethostbyname(HOSTNAME)
    except:
        return result
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(15)
    try:
        conn = s.connect((destIp, PORT))
        result = True
        conn.close()
    except:
        pass
    return result

if Ip:Port is reachable, return True

If you wanna to simulate Ping, may refer to ping.py

Underage answered 16/2, 2017 at 6:19 Comment(0)
S
1

Try this:

ret = os.system("ping -o -c 3 -W 3000 192.168.1.10")
if ret != 0:
    print "Host is not up"

-o waits for only one packet

-W 3000 gives it only 3000 ms to reply to the packet.

-c 3 lets it try a few times so that your ping doesnt run forever

Stealing answered 6/10, 2011 at 18:4 Comment(0)
R
0

Use this and parse the string output


import subprocess
output = subprocess.Popen(["ping.exe","192.168.1.1"],stdout = subprocess.PIPE).communicate()[0]

Repudiation answered 6/10, 2011 at 18:5 Comment(0)
T
0

How about the request module?

import requests

def ping_server(address):
    try:
        requests.get(address, timeout=1)
    except requests.exceptions.ConnectTimeout:
        return False

return True
  • No need to split urls to remove ports, or test ports, and no localhost false-positive.
  • Timeout amount doesn't really matter since it only hits the timeout when there is no server, which in my case meant performance no longer mattered. Otherwise, this returns at the speed of a request, which is plenty fast for me.
  • Timeout waits for the first bit, not total time, in case that matters.
Trochanter answered 26/10, 2021 at 21:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.