Server ping dengan Python

167

Dalam Python, apakah ada cara untuk melakukan ping ke server melalui ICMP dan mengembalikan TRUE jika server merespons, atau SALAH jika tidak ada respons?

Kudu
sumber

Jawaban:

112

Fungsi ini berfungsi di semua OS (Unix, Linux, macOS, dan Windows)
Python 2 dan Python 3

EDIT:
Oleh @radato os.system digantikan oleh subprocess.call. Ini menghindari kerentanan injeksi shell jika string nama host Anda mungkin tidak divalidasi.

import platform    # For getting the operating system name
import subprocess  # For executing a shell command

def ping(host):
    """
    Returns True if host (str) responds to a ping request.
    Remember that a host may not respond to a ping (ICMP) request even if the host name is valid.
    """

    # Option for the number of packets as a function of
    param = '-n' if platform.system().lower()=='windows' else '-c'

    # Building the command. Ex: "ping -c 1 google.com"
    command = ['ping', param, '1', host]

    return subprocess.call(command) == 0

Perhatikan bahwa, menurut @ikrase pada Windows, fungsi ini masih akan kembali Truejika Anda mendapatkan Destination Host Unreachablekesalahan.

Penjelasan

Perintahnya ada pingdi sistem Windows dan Unix-like.
Opsi -n(Windows) atau -c(Unix) mengontrol jumlah paket yang dalam contoh ini diatur ke 1.

platform.system()mengembalikan nama platform. Ex. 'Darwin'di macOS.
subprocess.call()melakukan panggilan sistem. Ex. subprocess.call(['ls','-l']).

ePi272314
sumber
14
Perhatikan bahwa ini masih akan mengembalikan true (di Windows) jika Anda mendapatkan balasan "host tujuan tidak terjangkau" dari host yang berbeda.
ikrase
Saya menemukan bahwa saya kadang-kadang akan mendapatkan ping sukses ketika modem saya mati ??? Itu sedang menguji "8.8.8.8" dan "google.com" pada OS Windows 10. Ada yang tidak beres.
Markus
Itu tidak bisa terjadi pada @Markus. Tolong, tes dengan tangan dan dengan versi modifikasi dari kode di atas, dan beri tahu kami hasilnya. Dengan tangan: 1) buka cmd 2) ping 8.8.8.8 -n 13) echo %ERRORLEVEL%. Kode: Ubah baris terakhir kode Python menjadi return system_call(command). Dengan konektivitas yang tepat Anda akan mendapatkan 0 (nol). Dengan modem Anda mati, Anda harus mendapatkan beberapa kode kesalahan. Tentu saja, kedua metode harus mengembalikan kode kesalahan yang sama dalam kondisi yang sama.
ePi272314
Itu memang terjadi dan saya menggunakan kode yang tepat, kata demi kata. Saya mengerti dan meyakini komentar Anda, tidak ada cara ping baris perintah bisa berhasil ketika tidak ada koneksi, maka saya pikir ada sesuatu yang tidak bekerja dengan benar di python untuk operasi perintah. Saya akan mencoba pembaruan dan melihat bagaimana hasilnya. Terima kasih.
Markus
@Markus melihat komentar ikrase.
Boris
163

Jika Anda tidak perlu mendukung Windows, berikut ini cara yang sangat ringkas untuk melakukannya:

import os
hostname = "google.com" #example
response = os.system("ping -c 1 " + hostname)

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

Ini berfungsi karena ping mengembalikan nilai bukan nol jika koneksi gagal. (Nilai pengembalian sebenarnya berbeda tergantung pada kesalahan jaringan.) Anda juga bisa mengubah batas waktu ping (dalam detik) menggunakan opsi '-t'. Catatan, ini akan menampilkan teks ke konsol.

10 aliran
sumber
42
Saya berakhir dengan varian iniresponse = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
MGP
4
@ jeckyll2hide man ping, kirim hanya 1 paket dengan batas waktu 2 detik dan redirect semua output ke / dev / null, ambil hanya nilai kembali.
MGP
@ManuelGutierrez Saya pikir Anda ingin "-W 2000" (batas waktu setelah 2000 milidetik) dan mungkin "-t 3" (keluar setelah 3 detik, tidak peduli apa)
eludom
1
-w dan -W mengambil nilai dalam hitungan detik bukan milidetik. Periksa man pinguntuk memastikan.
Alan Turing
7
Jika Anda mendapatkan hostnamestring dari pengguna, mereka dapat dengan mudah meretas server Anda dengan memberi Anda "url"'google.com; rm -rf /*' . Gunakan subprocess.run(["ping", "-c", "1", hostname]).returncodesebagai gantinya.
Boris
38

Ada modul yang disebut pyping yang dapat melakukan ini. Itu dapat diinstal dengan pip

pip install pyping

Sangat mudah digunakan, namun, ketika menggunakan modul ini, Anda memerlukan akses root karena fakta bahwa itu adalah pembuatan paket mentah di bawah tenda.

import pyping

r = pyping.ping('google.com')

if r.ret_code == 0:
    print("Success")
else:
    print("Failed with {}".format(r.ret_code))
Stephen Cochran
sumber
4
"Perhatikan bahwa pesan ICMP hanya dapat dikirim dari proses yang berjalan sebagai root (di Windows, Anda harus menjalankan skrip ini sebagai 'Administrator')."
Ben Hyde
1
Saya suka bahwa Anda dapat menentukan batas waktu dan jumlah permintaan ICMP yang dikirim. Saya dapat menulis skrip yang menemukan semua host di sub-net lokal. Ini dijalankan dalam 1 detik, bukannya 255 detik menggunakan os.system('ping -c 1 -t 1 hostname')solusi. Plus pypinglib sangat mudah digunakan dibandingkan dengan menggunakan perpustakaan soket TCP / IP. Saya menulis program ping saya menggunakan keduanya, dan pypingjauh lebih cepat dan lebih mudah digunakan, menurut pendapat saya, terutama jika orang tidak terbiasa dengan menggunakan perpustakaan soket TCP / IP.
MikeyE
10
tidak bekerja dengan py3. ModuleNotFoundError: Tidak ada modul bernama 'core'
alireza
2
kesalahan 'inti' berasal dari ketidakcocokan dengan python3. saya mencoba memperbaikinya untuk python3 tetapi terus mengirimi saya kesalahan. halaman penulis dan proyek github sedang down (404 tidak ditemukan). kita harus porting sendiri ke python3 :-)
Andre
6
untuk python3 coba ping3: github.com/kyan001/ping3 pip install ping3
beep_check
29
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()
mluebke
sumber
6
Satu-satunya masalah dengan ini adalah bahwa itu tidak akan berfungsi pada Windows.
Kudu
8
Harus disebutkan bahwa alasan sesuatu seperti ini diperlukan adalah bahwa ICMP memerlukan root, dan / bin / ping mengatasi ini dengan diset SUID.
Catskul
1
Catatan: Mungkin gagal jika ping di lokasi yang berbeda. Gunakan whereis pinguntuk mendapatkan jalur yang benar.
octern
4
Ini bekerja pada Windows:ping_response = subprocess.Popen(["ping", hostname, "-n", '1'], stdout=subprocess.PIPE).stdout.read()
Victor Lellis
1
Bagaimana saya bisa menguraikan hasilnya untuk memeriksa apakah responsnya ok atau ko di Windows?
Pitto
15

Untuk python3 ada modul python ping3 yang sangat sederhana dan nyaman : (pip install ping3 , membutuhkan hak akses root ).

from ping3 import ping, verbose_ping
ping('example.com')  # Returns delay in seconds.
>>> 0.215697261510079666

Modul ini memungkinkan penyesuaian beberapa parameter juga.

Александр Рублев
sumber
2
Seperti yang diedit memerlukan hak root, diskusi tentang mengangkat ini di sini: github.com/kyan001/ping3/issues/10
Dimitrios Mistriotis
1
Oh, perlu root prvilege tidak hanya untuk menginstal, tetapi juga untuk eksekusi: ping ("example.com")
Clock ZHONG
14

Karena saya suka memiliki program Python universal pada versi 2.7 dan 3.x dan pada platform Linux, Mac OS dan Windows, saya harus memodifikasi contoh yang ada.

# shebang does not work over all platforms
# ping.py  2016-02-25 Rudolf
# subprocess.call() is preferred to os.system()
# works under Python 2.7 and 3.4
# works under Linux, Mac OS, Windows

def ping(host):
    """
    Returns True if host responds to a ping request
    """
    import subprocess, platform

    # Ping parameters as function of OS
    ping_str = "-n 1" if  platform.system().lower()=="windows" else "-c 1"
    args = "ping " + " " + ping_str + " " + host
    need_sh = False if  platform.system().lower()=="windows" else True

    # Ping
    return subprocess.call(args, shell=need_sh) == 0

# test call
print(ping("192.168.17.142"))
Rudolf
sumber
1
Alih-alih False if platform.system().lower()=="windows" else Truetentunya Anda bisa juga menggunakan saja platform.system().lower() != "windows".
Frerich Raabe
Tidak os.name!="nt"juga berfungsi? Memang saya belum mencobanya di semua kombo ver / platform!
Keeely
2
Dalam kasus saya gateway default mengembalikan pesan 'tidak dapat dijangkau', tetapi perintah ping windows masih memiliki kode kembali 0. Jadi pendekatan ini berhasil (maaf untuk pemformatan - 6 barisnya, termasuk deklarasi functiontion): def ping(host): process = subprocess.Popen(["ping", "-n", "1",host], stdout=subprocess.PIPE, stderr=subprocess.PIPE) streamdata = process.communicate()[0] if 'unreachable' in str(streamdata): return 1 return process.returncode
wellspokenman
@wellspokenman Anda lebih suka mengembalikan 0 jika unreachableditemukan di dalam pipa, bukan?
beeb
1
@beeb ya saya juga melakukannya tetapi lupa untuk memperbarui komentar. Fungsi saya saat ini terlihat seperti ini: pastebin.com/FEYWsVjK
wellspokenman
8

Setelah melihat-lihat, saya akhirnya menulis modul ping saya sendiri, yang dirancang untuk memonitor sejumlah besar alamat, tidak sinkron dan tidak menggunakan banyak sumber daya sistem. Anda dapat menemukannya di sini: https://github.com/romana/multi-ping/ Ini berlisensi Apache, sehingga Anda dapat menggunakannya dalam proyek Anda dengan cara apa pun yang Anda inginkan.

Alasan utama untuk menerapkan saya sendiri adalah pembatasan dari pendekatan lain:

  • Banyak solusi yang disebutkan di sini membutuhkan exec ke utilitas baris perintah. Ini sangat tidak efisien dan sumber daya haus jika Anda perlu memonitor sejumlah besar alamat IP.
  • Yang lain menyebutkan beberapa modul ping python yang lebih lama. Saya melihat itu dan pada akhirnya, mereka semua memiliki masalah atau yang lainnya (seperti tidak mengatur ID paket dengan benar) dan tidak menangani ping dari banyak alamat.
Juergen Brendel
sumber
Teman kerja yang bagus! Jika ada yang ingin melihatnya beraksi, cukup gunakan github.com/romana/multi-ping/blob/master/demo.py
Cucu
7
#!/usr/bin/python3

import subprocess as sp

def ipcheck():
    status,result = sp.getstatusoutput("ping -c1 -w2 " + str(pop))
    if status == 0:
        print("System " + str(pop) + " is UP !")
    else:
        print("System " + str(pop) + " is DOWN !")


pop = input("Enter the ip address: ")
ipcheck()
Udayendu
sumber
Kode ini mungkin memiliki jawaban untuk pertanyaan, tetapi akan sangat membantu untuk menambahkan beberapa komentar atau penjelasan tentang bagaimana kode Anda memecahkan masalah.
skrrgwasme
5

Pastikan pyping diinstal atau instal pip instal pyping

#!/usr/bin/python
import pyping

response = pyping.ping('Your IP')

if response.ret_code == 0:
    print("reachable")
else:
    print("unreachable")
Naveen
sumber
1
Terima kasih! Namun, saya perlu menjalankan kode ini sebagai root untuk membuatnya bekerja.
Thomas
1
Halaman GitHub Pyping sudah tidak ada lagi dan paket PyPI belum diperbarui sejak 2016.
Stevoisiak
Saya mendapatkan kesalahan berikut: import pyping Traceback (panggilan terakhir terakhir): File "<stdin>", baris 1, di <module> File "/usr/local/lib/python3.6/dist-packages/pyping/__init__. py ", baris 3, dalam <module> dari impor inti * ModuleNotFoundError: Tidak ada modul bernama 'core'
Clock ZHONG
5

Ping ICMP terprogram rumit karena hak istimewa tinggi yang diperlukan untuk mengirim paket ICMP mentah, dan memanggil pingbiner jelek. Untuk pemantauan server, Anda dapat mencapai hasil yang sama menggunakan teknik yang disebut TCP ping :

# pip3 install tcping
>>> from tcping import Ping
# Ping(host, port, timeout)
>>> ping = Ping('212.69.63.54', 22, 60)
>>> ping.ping(3)
Connected to 212.69.63.54[:22]: seq=1 time=23.71 ms
Connected to 212.69.63.54[:22]: seq=2 time=24.38 ms
Connected to 212.69.63.54[:22]: seq=3 time=24.00 ms

Secara internal, ini hanya membuat koneksi TCP ke server target dan langsung menjatuhkannya, mengukur waktu yang berlalu. Implementasi khusus ini agak terbatas karena tidak menangani port yang tertutup tetapi untuk server Anda sendiri ia bekerja dengan cukup baik.

kravietz
sumber
4
#!/usr/bin/python3

import subprocess as sp

ip = "192.168.122.60"
status,result = sp.getstatusoutput("ping -c1 -w2 " + ip)

if status == 0: 
    print("System " + ip + " is UP !")
else:
    print("System " + ip + " is DOWN !")
Udayendu
sumber
3

Saya menyelesaikan ini dengan:

def ping(self, host):
    res = False

    ping_param = "-n 1" if system_name().lower() == "windows" else "-c 1"

    resultado = os.popen("ping " + ping_param + " " + host).read()

    if "TTL=" in resultado:
        res = True
    return res

"TTL" adalah cara untuk mengetahui apakah ping itu benar. Salud

pengguna3620655
sumber
3

Pengurangan saya menggunakan ide dari jawaban dalam posting ini tetapi hanya menggunakan modul subproses yang direkomendasikan dan python3 yang lebih baru:

import subprocess
import platform

operating_sys = platform.system()
nas = '192.168.0.10'

def ping(ip):
    # ping_command = ['ping', ip, '-n', '1'] instead of ping_command = ['ping', ip, '-n 1'] for Windows
    ping_command = ['ping', ip, '-n', '1'] if operating_sys == 'Windows' else ['ping', ip, '-c 1']
    shell_needed = True if operating_sys == 'Windows' else False

    ping_output = subprocess.run(ping_command,shell=shell_needed,stdout=subprocess.PIPE)
    success = ping_output.returncode
    return True if success == 0 else False

out = ping(nas)
print(out)
Arno
sumber
1
Anda tidak perlu menggunakan True if condition else Falseuntuk mengembalikan Benar atau Salah berdasarkan kondisi. Cukup gunakan mis shell_needed = operating_sys == 'Windows'danreturn success == 0
emorris
2

Skrip ini berfungsi pada Windows, dan harus bekerja pada OS lain: Ini berfungsi pada Windows, Debian, dan macosx, perlu tes pada solaris.

import os
import platform


def isUp(hostname):

    giveFeedback = False

    if platform.system() == "Windows":
        response = os.system("ping "+hostname+" -n 1")
    else:
        response = os.system("ping -c 1 " + hostname)

    isUpBool = False
    if response == 0:
        if giveFeedback:
            print hostname, 'is up!'
        isUpBool = True
    else:
        if giveFeedback:
            print hostname, 'is down!'

    return isUpBool

print(isUp("example.com")) #Example domain
print(isUp("localhost")) #Your computer
print(isUp("invalid.example.com")) #Unresolvable hostname: https://tools.ietf.org/html/rfc6761
print(isUp("192.168.1.1")) #Pings local router
print(isUp("192.168.1.135")) #Pings a local computer - will differ for your network
Matius
sumber
Jawaban yang bagus. Tidak ada hak admin yang diperlukan untuk Windows di sini.
pendaki gunung
Apakah saya menerima IP Benar atau salah
joash
Ya ini pasti tidak berhasil. Hanya mengembalikan: "true" di Windows
MKANET
2

Saya akhirnya menemukan pertanyaan ini mengenai skenario yang sama. Saya mencoba pyping tetapi contoh yang diberikan oleh Naveen tidak bekerja untuk saya di Windows di bawah Python 2.7.

Contoh yang berhasil bagi saya adalah:

import pyping

response = pyping.send('Your IP')

if response['ret_code'] == 0:
    print("reachable")
else:
    print("unreachable")
Berkenaan dgn pura
sumber
1
pypingtampaknya bukan modul standar. Mungkin Anda bisa memberikan tautan?
Mawg mengatakan mengembalikan Monica
2

Menggunakan Multi-ping ( pip install multiPing) saya membuat kode sederhana ini ( cukup salin dan tempel jika mau! ):

from multiping import MultiPing

def ping(host,n = 0):
    if(n>0):
        avg = 0
        for i in range (n):
            avg += ping(host)
        avg = avg/n
    # Create a MultiPing object to test hosts / addresses
    mp = MultiPing([host])

    # Send the pings to those addresses
    mp.send()

    # With a 1 second timout, wait for responses (may return sooner if all
    # results are received).
    responses, no_responses = mp.receive(1)


    for addr, rtt in responses.items():
        RTT = rtt


    if no_responses:
        # Sending pings once more, but just to those addresses that have not
        # responded, yet.
        mp.send()
        responses, no_responses = mp.receive(1)
        RTT = -1

    return RTT

Pemakaian:

#Getting the latency average (in seconds) of host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)

Jika Anda ingin sampel tunggal, " 10" parameter kedua dapat diabaikan!

Semoga ini bisa membantu!

Geraldo Neto
sumber
4
perpustakaan yang mengagumkan, tetapi membutuhkan hak akses root.
Craynic Cai
2

Versi saya dari fungsi ping:

  • Bekerja pada Python 3.5 dan yang lebih baru, pada Windows dan Linux (harus bekerja pada Mac, tetapi tidak dapat mengujinya).
  • Di Windows, mengembalikan False jika perintah ping gagal dengan "Destination Host Unreachable".
  • Dan tidak menunjukkan output apa pun, baik sebagai jendela sembul atau di baris perintah.
import platform, subprocess

def ping(host_or_ip, packets=1, timeout=1000):
    ''' Calls system "ping" command, returns True if ping succeeds.
    Required parameter: host_or_ip (str, address of host to ping)
    Optional parameters: packets (int, number of retries), timeout (int, ms to wait for response)
    Does not show any output, either as popup window or in command line.
    Python 3.5+, Windows and Linux compatible (Mac not tested, should work)
    '''
    # The ping command is the same for Windows and Linux, except for the "number of packets" flag.
    if platform.system().lower() == 'windows':
        command = ['ping', '-n', str(packets), '-w', str(timeout), host_or_ip]
        # run parameters: capture output, discard error messages, do not show window
        result = subprocess.run(command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, creationflags=0x08000000)
        # 0x0800000 is a windows-only Popen flag to specify that a new process will not create a window.
        # On Python 3.7+, you can use a subprocess constant:
        #   result = subprocess.run(command, capture_output=True, creationflags=subprocess.CREATE_NO_WINDOW)
        # On windows 7+, ping returns 0 (ok) when host is not reachable; to be sure host is responding,
        # we search the text "TTL=" on the command output. If it's there, the ping really had a response.
        return result.returncode == 0 and b'TTL=' in result.stdout
    else:
        command = ['ping', '-c', str(packets), '-w', str(timeout), host_or_ip]
        # run parameters: discard output and error messages
        result = subprocess.run(command, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        return result.returncode == 0

Jangan ragu untuk menggunakannya sesuka Anda.

Jose Francisco Lopez Pimentel
sumber
1

Tampaknya cukup sederhana, tetapi memberi saya cocok. Saya terus mendapatkan "operasi soket terbuka icmp tidak diizinkan" atau solusi akan menutup jika server off line. Namun, jika yang ingin Anda ketahui adalah bahwa server masih hidup dan Anda menjalankan server web di server itu, maka curl akan melakukan pekerjaan itu. Jika Anda memiliki ssh dan sertifikat, maka ssh dan perintah sederhana sudah cukup. Ini kodenya:

from easyprocess import EasyProcess # as root: pip install EasyProcess
def ping(ip):
    ping="ssh %s date;exit"%(ip) # test ssh alive or
    ping="curl -IL %s"%(ip)      # test if http alive
    response=len(EasyProcess(ping).call(timeout=2).stdout)
    return response #integer 0 if no response in 2 seconds
pengguna2099484
sumber
1

Saya memiliki persyaratan yang serupa jadi saya menerapkannya seperti yang ditunjukkan di bawah ini. Ini diuji pada Windows 64 bit dan Linux.

import subprocess
def systemCommand(Command):
    Output = ""
    Error = ""     
    try:
        Output = subprocess.check_output(Command,stderr = subprocess.STDOUT,shell='True')
    except subprocess.CalledProcessError as e:
        #Invalid command raises this exception
        Error =  e.output 

    if Output:
        Stdout = Output.split("\n")
    else:
        Stdout = []
    if Error:
        Stderr = Error.split("\n")
    else:
        Stderr = []

    return (Stdout,Stderr)

#in main
Host = "ip to ping"
NoOfPackets = 2
Timeout = 5000 #in milliseconds
#Command for windows
Command = 'ping -n {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
#Command for linux 
#Command = 'ping -c {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
Stdout,Stderr = systemCommand(Command)
if Stdout:
   print("Host [{}] is reachable.".format(Host))
else:
   print("Host [{}] is unreachable.".format(Host))

Ketika IP tidak dapat dijangkau, subprocess.check_output () memunculkan pengecualian. Verifikasi ekstra dapat dilakukan dengan mengekstraksi informasi dari baris keluaran 'Paket: Terkirim = 2, Diterima = 2, Hilang = 0 (kerugian 0%)'.

Luminos
sumber
1

Inilah solusi menggunakan subprocessmodul Python dan pingalat CLI yang disediakan oleh OS yang mendasarinya. Diuji pada Windows dan Linux. Dukungan pengaturan batas waktu jaringan. Tidak memerlukan hak akses root (setidaknya di Windows dan Linux).

import platform
import subprocess

def ping(host, network_timeout=3):
    """Send a ping packet to the specified host, using the system "ping" command."""
    args = [
        'ping'
    ]

    platform_os = platform.system().lower()

    if platform_os == 'windows':
        args.extend(['-n', '1'])
        args.extend(['-w', str(network_timeout * 1000)])
    elif platform_os in ('linux', 'darwin'):
        args.extend(['-c', '1'])
        args.extend(['-W', str(network_timeout)])
    else:
        raise NotImplemented('Unsupported OS: {}'.format(platform_os))

    args.append(host)

    try:
        if platform_os == 'windows':
            output = subprocess.run(args, check=True, universal_newlines=True).stdout

            if output and 'TTL' not in output:
                return False
        else:
            subprocess.run(args, check=True)

        return True
    except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
        return False
Epoc
sumber
0

Gunakan ini diuji pada python 2.7 dan berfungsi baik mengembalikan waktu ping dalam milidetik jika berhasil dan mengembalikan False saat gagal.

import platform,subproccess,re
def Ping(hostname,timeout):
    if platform.system() == "Windows":
        command="ping "+hostname+" -n 1 -w "+str(timeout*1000)
    else:
        command="ping -i "+str(timeout)+" -c 1 " + hostname
    proccess = subprocess.Popen(command, stdout=subprocess.PIPE)
    matches=re.match('.*time=([0-9]+)ms.*', proccess.stdout.read(),re.DOTALL)
    if matches:
        return matches.group(1)
    else: 
        return False
MSS
sumber
0

Satu hal yang terlewatkan oleh banyak jawaban adalah (setidaknya di Windows) ping perintah mengembalikan 0 (menunjukkan keberhasilan) jika menerima balasan "Host tujuan tidak dapat dijangkau."

Berikut adalah kode saya yang memeriksa apakah b'TTL='ada dalam respons, karena hanya ada saat ping mencapai host. Catatan: Sebagian besar kode ini didasarkan pada jawaban lain di sini.

import platform
import subprocess

def ping(ipAddr, timeout=100):
    '''
    Send a ping packet to the specified host, using the system ping command.
    Accepts ipAddr as string for the ping destination.
    Accepts timeout in ms for the ping timeout.
    Returns True if ping succeeds otherwise Returns False.
        Ping succeeds if it returns 0 and the output includes b'TTL='
    '''
    if platform.system().lower() == 'windows':
        numFlag = '-n'
    else:
        numFlag = '-c'
    completedPing = subprocess.run(['ping', numFlag, '1', '-w', str(timeout), ipAddr],
                                   stdout=subprocess.PIPE,    # Capture standard out
                                   stderr=subprocess.STDOUT)  # Capture standard error
    # print(completedPing.stdout)
    return (completedPing.returncode == 0) and (b'TTL=' in completedPing.stdout)

print(ping('google.com'))

Catatan: Ini menangkap output alih-alih mencetaknya, jadi jika Anda ingin melihat outputnya ping, Anda harus mencetak completedPing.stdoutsebelum kembali.

Brent Robertson
sumber
0

WINDOWS ONLY - Tidak dapat dipercaya tidak ada yang membuka Win32_PingStatus menggunakan kueri WMI sederhana, kami mengembalikan objek yang penuh dengan informasi yang sangat detail secara gratis

import wmi


# new WMI object
c = wmi.WMI()

# here is where the ping actually is triggered
x = c.Win32_PingStatus(Address='google.com')

# how big is this thing? - 1 element
print 'length x: ' ,len(x)


#lets look at the object 'WMI Object:\n'
print x


#print out the whole returned object
# only x[0] element has values in it
print '\nPrint Whole Object - can directly reference the field names:\n'
for i in x:
    print i



#just a single field in the object - Method 1
print 'Method 1 ( i is actually x[0] ) :'
for i in x:
    print 'Response:\t', i.ResponseTime, 'ms'
    print 'TTL:\t', i.TimeToLive


#or better yet directly access the field you want
print '\npinged ', x[0].ProtocolAddress, ' and got reply in ', x[0].ResponseTime, 'ms'

output sampel

Aimondy
sumber
0

Saya menerima pinjaman dari jawaban lain. Berusaha menyederhanakan dan meminimalkan pertanyaan.

import platform, os

def ping(host):
    result = os.popen(' '.join(("ping", ping.param, host))).read()
    return 'TTL=' in result

ping.param = "-n 1" if platform.system().lower() == "windows" else "-c 1"
misantroop
sumber
0

Saya memerlukan sapuan ping yang lebih cepat dan saya tidak ingin menggunakan perpustakaan eksternal, jadi saya memutuskan untuk menggunakan konkurensi menggunakan built-in asyncio.

Kode ini membutuhkan python 3.7+ dan dibuat dan diuji di Linux saja. Itu tidak akan berfungsi pada Windows tetapi saya yakin Anda dapat dengan mudah mengubahnya untuk bekerja pada Windows.

Saya bukan ahli dengan asynciotetapi saya menggunakan artikel hebat ini Mempercepat Program Python Anda Dengan Concurrency dan saya datang dengan baris kode ini. Saya mencoba membuatnya sesederhana mungkin, jadi kemungkinan besar Anda perlu menambahkan lebih banyak kode sesuai kebutuhan Anda.

Itu tidak mengembalikan benar atau salah, saya pikir akan lebih nyaman hanya dengan membuatnya mencetak IP yang menanggapi permintaan ping. Saya pikir ini cukup cepat, ping 255 ips dalam hampir 10 detik.

#!/usr/bin/python3

import asyncio

async def ping(host):
    """
    Prints the hosts that respond to ping request
    """
    ping_process = await asyncio.create_subprocess_shell("ping -c 1 " + host + " > /dev/null 2>&1")
    await ping_process.wait()

    if ping_process.returncode == 0:
        print(host)
    return 


async def ping_all():
    tasks = []

    for i in range(1,255):
        ip = "192.168.1.{}".format(i)
        task = asyncio.ensure_future(ping(ip))
        tasks.append(task)

    await asyncio.gather(*tasks, return_exceptions = True)

asyncio.run(ping_all())

Output sampel:

192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6

Perhatikan bahwa IP tidak dalam urutan, karena IP dicetak segera setelah itu menjawab, sehingga yang menjawab pertama akan dicetak terlebih dahulu.

Ahmed Essam
sumber
-3
  1 #!/usr/bin/python
  2
  3 import os
  4 import sys
  5 import time
  6
  7 os.system("clear")
  8 home_network = "172.16.23."
  9 mine = []
 10
 11 for i in range(1, 256):
 12         z =  home_network + str(i)
 13         result = os.system("ping -c 1 "+ str(z))
 14         os.system("clear")
 15         if result == 0:
 16                 mine.append(z)
 17
 18 for j in mine:
 19         print "host ", j ," is up"

Yang sederhana saya baru saja memasak dalam satu menit..menggunakan icmplib membutuhkan root privs di bawah ini bekerja cukup baik! HTH

pengguna3423128
sumber