年前大多数外地的同事都提前请假回家,我家是西安的,所以一直上班到2月1号,其实后来那几天人已经很少了。闲得实在无聊, 于是就想看看网段中有多少机子开着机,但是手头又没有现成的 LAN 工具。于是打算用 python 玩一下。
我工作在 windows 系统下,不知道 python 中有没有现在的 ping 模块,不过也懒得找,打算直接 os.popen()
执行 ping
命令,
根据返回结果来得知是否 ping 得通。
通常 cmd 下 ping 成功 的结果如下:
Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Ping statistics for 127.0.0.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
ping 命令默认会发送 4 个数据包,为了保险起见,我手动指定为 4 个
ping -n 4 <IP_ADDRESS>
起始我是一个 IP 一个 IP 的 ping ,不过这样速度很慢,大多数时间都用在等待上面了,显然得上 threading 了。
class Ping(threading.Thread):
def __init__(self, ip_address):
threading.Thread.__init__(self)
self.ip_address = ip_address
def run(self):
# ping 指定的IP地址,并返回丢失的包数
result = os.popen('ping -n 4 %s' % self.ip_address).read()
match = RESULT_PATTERN.search(result)
lost_count = match and int(match.group(1)) or 0
if lost_count == 0:
print 'ping %-15s stabled' % self.ip_address
elif lost_count == 4:
print 'ping %-15s timeout' % self.ip_address
else:
print 'ping %-15s unstable' % self.ip_address
指定网段循环的 ping 了下,结果打印出来的结果一片混乱(事实上在多线程中直接在屏幕上打印信息是个很愚蠢的作法), 看来得在打印这部分上做一些处理,于是就得用上 Lock
lock = threading.Lock()
# ...
lock.acquire()
if lost_count == 0:
print 'ping %-15s stabled' % self.ip_address
elif lost_count == 4:
print 'ping %-15s timeout' % self.ip_address
else:
print 'ping %-15s unstable' % self.ip_address
lock.release()
完整的代码:
# coding: utf-8
"""
ping一个网段,并列出结果
"""
import os, re, threading
RESULT_PATTERN = re.compile(r'Lost\s=\s(\d)', re.M)
class Ping(threading.Thread):
def __init__(self, ip_address):
threading.Thread.__init__(self)
self.ip_address = ip_address
def run(self):
# ping 指定的IP地址,并返回丢失的包数
result = os.popen('ping -n 4 %s' % self.ip_address).read()
match = RESULT_PATTERN.search(result)
lost_count = match and int(match.group(1)) or 0
# 加锁以防止屏幕打印混乱
global lock
lock.acquire()
if lost_count == 0:
print 'ping %-15s stabled' % self.ip_address
elif lost_count == 4:
print 'ping %-15s timeout' % self.ip_address
else:
print 'ping %-15s unstable' % self.ip_address
lock.release()
def bulk_ping(ip_prefix, start=0, end=255):
print 'pinging ip addresses from %s.%d to %s.%d' % (ip_prefix, start, ip_prefix, end)
for i in range(start, end):
ping_thread = Ping('%s.%d' % (ip_prefix, i))
ping_thread.start()
if __name__ == '__main__':
global lock
lock = threading.Lock()
bulk_ping('10.144.114')</pre>