参考链接:https://blog.csdn.net/weixin_43484977/article/details/103339073
python 模拟ping值检测
- 先创建一个aaa.txt文档,里面每一行存一个ip地址
import threading
import os
import struct
import array
import time
import socket
import threading
class SendPingThread(threading.Thread): #发送ping线程,继承Thread
def __init__(self, ipPool, icmpPacket, icmpSocket, timeout=0.5): #ip池,icmp协议包,icmp协议套接字,超时时间
threading.Thread.__init__(self)
self.sock = icmpSocket
self.ipPool = ipPool
self.packet = icmpPacket
self.timeout = timeout
self.sock.settimeout(timeout)
def run(self): #run方法 start的时候调用
time.sleep(0.01)
for ip in self.ipPool: #遍历ip地址池
try:
self.sock.sendto(self.packet, (ip, 0)) #发送消息 # 利用套截字发送icmp包
except socket.timeout: #超时异常
break
class AliveScan:
def __init__(self, timeout=3):
self.timeout = timeout
self._data = struct.pack('d', time.time()) #按d类型打包,把时间戳打包,生成8个字节的字节类型对象
self._id = os.getpid() #进程id 作为报文中的Identifier字段(必须是int)
@property
def icmp_socket(self): #创建套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))
return sock
def check_sum(self, packet): #计算校验和
if len(packet) & 1:
packet = packet + '\0'
words = array.array('h', packet)
sum = 0
#为了计算一份数据报的IP检验和,首先把检验和字段置为0。
# 然后,对首部中每个16bit进行二进制反码求和(整个首部看成是由一串16bit的字组成),结果存在检验和字段中。
for word in words: #对每一个16bits (字)进行反码求和
sum += (word & 0xffff)
sum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
return (~sum) & 0xffff
@property
def icmp_packet(self): #icmp包
header = struct.pack('bbHHh', 8, 0, 0, self._id, 0) #报文头 pack 的时候 按照参数个数进行pack, 前面的bbHHh是类型,
packet = header + self._data # 报文头+数据 d 得到包 这里的+ 是单纯的连在一起么?
chkSum = self.check_sum(packet) #把包进行校验
header = struct.pack('bbHHh', 8, 0, chkSum, self._id, 0) #再pack打包
return header + self._data
def hot_ping(self, ipPool): #ip池 传进来,循环
sock = self.icmp_socket
sock.settimeout(self.timeout)
packet = self.icmp_packet
recvFroms = set() #空集合
sendThr = SendPingThread(ipPool, packet, sock, self.timeout) #创建发送线程
sendThr.start() #启动,自动调用run方法,发送icmp包了已经
while True:
try:
msg,addr = sock.recvfrom(1024) #接受信息,获取到地址,那么这里接收到的msg里面有时间戳么,怎么获取时间戳,然后计算ping值响应时间?
# 接收返回值
if addr[0] not in ipPool: #如果ping不通,接收到的是本机地址,本机地址不在ipPool池里
print('不通')
else:print('通')
except Exception:
pass
finally:
if not sendThr.is_alive(): #线程不是激活的状态,就结束循环
break
return recvFroms & ipPool #交集
def get_alive_ip():
s = AliveScan() #实例化扫描类
ipPool = set() #空集合 ip池
with open('aaa.txt') as file_obj:
ips = file_obj.read()
ips_list = ips.strip().split('\n')
ipPool = set(ips_list[:20]) #列表切片, 只取前20个 放到集合中
alive_ip_set = set()
for ip in ipPool:
print('ping '+ip)
alive_ips = s.hot_ping(set([ip, ]))
if alive_ips:
# print type(alive_ips)
alive_ip_set = alive_ip_set | alive_ips #取并集
return alive_ip_set
get_alive_ip()
- 结果:
![]()

浙公网安备 33010602011771号