[Python]Pingで死活監視を行う

Python

はじめに

PythonにてPingで死活監視を行う方法を紹介します。

しげっち
しげっち

死活監視を行う方法は3通りの方法があるよ。

  • subprocessモジュールを用いる方法
  • ping3モジュールを用いる方法
  • Pingsモジュールを用いる方法
にゃーすけ
にゃーすけ

3通りもあるのにゃ!

しげっち
しげっち

ただし、Pingsの方法はPythonのバージョンが3.8以降だとエラーになってしまうんだ。
また2017年以降更新されていないので、おすすめする使用方法は2通りになるよ!

subprocessを用いる方法

subprocessというモジュールで、OSのpingコマンドを実行する方法です。

Python標準の機能であるため、インストール作業は不要です。
subprocessをimportすることで使用できます。

このsubprocessですが、pythonでpingを実行するためだけのモジュールではありません。
pythonでシェルコマンドを実行するためのモジュールです。

そしてこのページでは、シェルコマンドの一つであるpingの使用方法についての解説になります。

下記サンプルでは3つのアドレスに対してPingを各2回実行し、
疎通確認が取れたら「成功」取れなかったら「失敗」を表示させます。
windowsの場合は引数の-cが-nになります

import subprocess

hosts = ["192.168.0.1","192.168.0.18","192.168.0.200"]

for host in hosts:
    res = subprocess.run(["ping",host,"-c","2", "-W", "300"],stdout=subprocess.PIPE)

    print(res.stdout.decode("cp932"))
    
    if res.returncode == 0 :
        print("成功\n\n")
    else:
        print("失敗\n\n")
    print("-----------------------------")

6行目、引数の-cは疎通確認を行う回数指定です。
その次の引数のが実際の回数になります。

引数-Wはタイムアウトの指定です。
小文字だとエラーになるので注意です。
その次の引数の300が実際のタイムアウトの数値です。
ミリ秒単位で指定します。

実行結果は下記です。

PING 192.168.0.1 (192.168.0.1): 56 data bytes
64 bytes from 192.168.0.1: icmp_seq=0 ttl=255 time=7.763 ms
64 bytes from 192.168.0.1: icmp_seq=1 ttl=255 time=8.346 ms

--- 192.168.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 7.763/8.055/8.346/0.291 ms

成功


-----------------------------
PING 192.168.0.18 (192.168.0.18): 56 data bytes
64 bytes from 192.168.0.18: icmp_seq=0 ttl=64 time=42.881 ms
64 bytes from 192.168.0.18: icmp_seq=1 ttl=64 time=71.887 ms

--- 192.168.0.18 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 42.881/57.384/71.887/14.503 ms

成功


-----------------------------
PING 192.168.0.200 (192.168.0.200): 56 data bytes
Request timeout for icmp_seq 0

--- 192.168.0.200 ping statistics ---
2 packets transmitted, 0 packets received, 100.0% packet loss

失敗


-----------------------------
しげっち
しげっち

subprocessの方法には一つ注意点があって、windowsやMac等OSによって設定する引数が変わってしまうんだ。

にゃーすけ
にゃーすけ

使用するOSが決まっていれば良いけど、決まってなければ気をつけないといけないにゃ。


ping3モジュールを用いる方法

次はping3モジュールを用いる方法です。
こちらは標準モジュールではないため、インストールする必要があります。

ping3のインストール

pip install ping3

pings3にはpingverbose_pingという2つの関数があります。
違いは、pingの場合は1回だけpingを実行を行うのに対し、verbose_pingは複数回、もしくは無制限にpingを実行する事ができます。

また、戻り値が異なります。

ping3のインポート

下記のようにインポートします。

from ping3 import ping, verbose_ping

ping関数

まずはping関数から見てみましょう。

print(ping('8.8.8.8'))
# 0.022598743438720703

実行すると応答時間が秒単位で返ってきます。

print(ping('abcde'))
# False

ホストとして解決できない場合はFalseを返します。

print(ping('222.8.8.8'))
# None

応答がなければNoneを返します。通常の待機時間は4秒です。
後ほど紹介するオプションで待機時間は変更できます。

2つ目の引数にオプションをつける事ができます。

# 待機時間を指定
print(ping('222.8.8.8', timeout = 10))
# None

# 戻り値の時間をミリ秒単位にする。デフォルトは秒単位の's'
print(ping('8.8.8.8', unit='ms'))
# 17.52328872680664

# パケットの存続可能時間を設定
print(ping('8.8.8.8', ttl=8))
# False

verbose_ping関数

続いてverbose_ping関数を見ていきましょう。

# print(verbose_ping('8.8.8.8'))
# ping '8.8.8.8' ... 17ms
# ping '8.8.8.8' ... 15ms
# ping '8.8.8.8' ... 15ms
# ping '8.8.8.8' ... 15ms
#None

ping関数との違いは複数回pingを実行すること(通常4回)と、戻り値がping ホスト … 応答時間(ms単位)となっています。

pingが終わったら最後にNoneが返ります。

ping関数と同様に2つ目の引数でオプションを指定できます。

# pingの回数を指定。countを0にすると無限に実行 ※ctrl+cで停止
print(verbose_ping('8.8.8.8', count=8))
# ping '8.8.8.8' ... 16ms
# ping '8.8.8.8' ... 17ms
# ping '8.8.8.8' ... 16ms
# ping '8.8.8.8' ... 15ms
# ping '8.8.8.8' ... 16ms
# ping '8.8.8.8' ... 16ms
# ping '8.8.8.8' ... 17ms
# ping '8.8.8.8' ... 20ms
# # None

# 待機時間を設定
print(verbose_ping('222.8.8.8', timeout = 5))
# ping '222.8.8.8' ... Timeout > 5s
# ping '222.8.8.8' ... Timeout > 5s
# ping '222.8.8.8' ... Timeout > 5s
# ping '222.8.8.8' ... Timeout > 5s
# None

# pingの間隔時間を秒単位で指定
print(verbose_ping('8.8.8.8', interval=2))
# ping '8.8.8.8' ... 16ms
# ping '8.8.8.8' ... 22ms
# ping '8.8.8.8' ... 17ms
# ping '8.8.8.8' ... 22ms
# None

上記サンプルでは省略しましたがttlunitオプションも使用できます。

引数を増やすことでオプションを複数指定することもできます。

#pingを6回2秒間隔で待機時間5秒にして実行
print(verbose_ping('8.8.8.8', count=6, interval=2, timeout=5))
# ping '8.8.8.8' ... 17ms
# ping '8.8.8.8' ... 24ms
# ping '8.8.8.8' ... 18ms
# ping '8.8.8.8' ... 22ms
# ping '8.8.8.8' ... 22ms
# ping '8.8.8.8' ... 23ms
# None

にゃーすけ
にゃーすけ

細かくオプションが指定できるから使いやすそうだにゃ!

Pingsモジュールを用いる方法

こちらの方法は推奨していないですが、紹介しておきます。

まずはPingsモジュールをインストールする必要があります。

pip install pings

下記サンプルを入力してみましょう。

import pings

hosts = ["192.168.0.1","192.168.0.18","192.168.0.200"]

p = pings.Ping()
for host in hosts:
    res = p.ping(host, times=2)

    res.print_messages()

    if res.is_reached():
        print('成功\n\n')
    else:
        print('失敗\n\n')

実行する際に注意点があり、管理者権限で実行する必要があります。
こうしないと、本当は成功であっても失敗で返ってきてしまいます

windowsの場合はコマンドプロンプトを管理者権限で開いて実行してください。
macの場合はターミナルでsudoをつけて実行してください。

ターミナルでの実行例

sudo python ping_test.py

実行結果

PING 192.168.0.1 (192.168.0.1): 55 data bytes
47 bytes from 192.168.0.1: icmp_seq=0 ttl=255 time=8.963 ms
47 bytes from 192.168.0.1: icmp_seq=1 ttl=255 time=2.531 ms
--- 192.168.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max = 2.531/5.747/8.963 ms
成功


PING 192.168.0.18 (192.168.0.18): 55 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
--- 192.168.0.18 ping statistics ---
2 packets transmitted, 0 packets received, 100.0% packet loss
round-trip min/avg/max = 0.000/0.000/0.000 ms
失敗


PING 192.168.0.200 (192.168.0.200): 55 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
--- 192.168.0.200 ping statistics ---
2 packets transmitted, 0 packets received, 100.0% packet loss
round-trip min/avg/max = 0.000/0.000/0.000 ms
失敗
しげっち
しげっち

以上、Pythonでの通信確認の方法でした。
なにかのお役に立てれば幸いです。

タイトルとURLをコピーしました