通过轮询ping IP来查找共有多少电脑处于联网状态

要求实现遍历一个指定的IP范围(例如:66.16.1.1到66.16.254.254),每批次处理一定数量的IP(这里设置为50个),并尝试对每个IP进行ping操作。如果ping成功,将IP地址写入到指定的输出文件中

共分两步:1、统计ping通的IP。2、计算每个小IP段是多少个IP

一、单线程处理方式

#单线程
import subprocess
from ftplib import all_errors

# 设置IP范围和输出文件路径
start_ip = "66.16.1.1"
end_ip = "66.16.254.254"
output_file = "ping_results.txt"


# 辅助函数,将IP地址转换为整数
def ip_to_int(ip):
    return int("".join([format(int(x), '08b') for x in ip.split(".")]), 2)

# 辅助函数,将整数转换回IP地址格式
def int_to_ip(num):
    return ".".join([str(num >> (i << 3) & 0xFF) for i in range(3, -1, -1)])


# 将IP地址转换为整数以便进行范围检查
start = int(ip_to_int(start_ip))
end = int(ip_to_int(end_ip))
# 确保输出文件存在
with open(output_file, 'w') as f:
    f.write("# IP Range: 66.16.1.1 to 66.16.254.254\n")

# 遍历IP范围
current = start
while current <= end:
    ip = int_to_ip(current)
    try:
        # 尝试ping IP
        response = subprocess.run(["ping", "-n", "1", ip], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=3)
        if response.returncode == 0:
            print('ping',ip,'成功')
            # Ping成功,写入文件
            with open(output_file, 'a') as f:
                f.write(f"{current}: {ip}\n")
    except Exception as e:
        print(f"inallyError pinging {ip}: {e}")

    # 每50个IP写入一次
    if (current - start) % 50 == 0 and current != start:
        print(f"Processed {(current - start) // 50 * 50} IPs")

    # 准备下一个IP
    current += 1

print("IP range ping completed.")

#单线程
import subprocess
from ftplib import all_errors
import os

# 设置IP范围和输出文件路径
start_ip = "66.16.10.1"
end_ip = "66.16.254.254"
output_file = "ping_results.txt"
count_file = r'ping_count.txt' #汇总日志文件


# 辅助函数,将IP地址转换为整数
def ip_to_int(ip):
    return int("".join([format(int(x), '08b') for x in ip.split(".")]), 2)


# 辅助函数,将整数转换回IP地址格式
def int_to_ip(num):
    return ".".join([str(num >> (i << 3) & 0xFF) for i in range(3, -1, -1)])


# 将IP地址转换为整数以便进行范围检查
start = int(ip_to_int(start_ip))
end = int(ip_to_int(end_ip))

# 确保输出文件存在
with open(output_file, 'w', encoding='utf-8') as f:
    f.write("# IP Range: 66.16.19.1 to 66.16.254.254\n")
with open(count_file, 'w', encoding='utf-8') as f:
    f.write("#每个网段可ping通个数:网段,可ping通数量\n")

k = int(int_to_ip(start).split('.')[2])
count=0
# 遍历IP范围
current = start
while current <= end:
    ip = int_to_ip(current)
    last = int(int_to_ip(current).split('.')[2])
    if k == last - 1:
        print(f"网段{k}中,有{count}个可ping通的ip")
        #以下两个注释应至少解开一个,以便有本地存储的汇总日志
        #注释以下两行,可通ping_results.txt中不写汇总
        # with open(output_file, 'a', encoding='utf-8') as f:
        #     f.write(f"网段{k}中,有{count}个可ping通的ip\n")

        #注释以下两行,不写入ping_count.txt文件
        with open(count_file, 'a', encoding='utf-8') as f:
            f.write(f"{k},{count}\n")

        k = last
        count = 0
    try:
        # 尝试ping IP
        response = subprocess.run(["ping", "-c", "1", ip], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        if response.returncode == 0:
            print(ip, '成功')
            # Ping成功,写入文件
            with open(output_file, 'a', encoding='utf-8') as f:
                f.write(f"{current}: {ip}\n")
            count += 1
        else:
            print(ip, "失败")
    except Exception as e:
        print(f"Error pinging {ip}: {e}")

    # 每50个IP写入一次
    if (current - start) % 50 == 0 and current != start:
        print(f"Processed {(current - start) // 50 * 50} IPs")

    # 准备下一个IP
    current += 1

print("IP range ping completed.")

二、多线程处理方式

#多线程
import subprocess
import threading

# 设置IP范围和输出文件路径
start_ip = "66.16.12.1"
end_ip = "66.16.254.254"
output_file = "ping_results.txt"
with open(output_file, 'w', encoding='utf-8') as f:
    f.write("# IP Range: 66.16.19.1 to 66.16.254.254\n")

# 辅助函数,将IP地址转换为整数
def ip_to_int(ip):
    return sum(int(part) << (24 - 8 * i) for i, part in enumerate(ip.split(".")))

# 辅助函数,将整数转换为IP地址
def int_to_ip(num):
    return '.'.join(str((num >> (24 - 8 * i)) & 0xFF) for i in range(4))

# 写入文件的函数
def write_to_file(ip):
    with open(output_file, 'a') as f:
        f.write(f"{ip}\n")

# 线程工作函数
def ping_ip(ip):
    pass
    try:
        # 尝试ping IP
        response = subprocess.run(["ping", "-n", "1", ip], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        if response.returncode == 0:
            # Ping成功,调用write_to_file函数写入文件
            write_to_file(ip)
            print(ip, '成功')
        else:
            print(ip, '失败')
    except Exception as e:
        print(f"Error pinging {ip}: {e}")

# 计算IP地址范围
start_int = ip_to_int(start_ip)
end_int = ip_to_int(end_ip)

# 创建线程安全的队列
from queue import Queue
ip_queue = Queue()

# 填充IP队列
for ip_int in range(start_int, end_int + 1):
    ip = int_to_ip(ip_int)
    ip_queue.put(ip)

# 定义线程数量
num_threads = 10

# 线程工作函数,从队列中获取IP并执行ping操作
def worker(ip_queue):
    while not ip_queue.empty():
        ip = ip_queue.get()
        ping_ip(ip)
        ip_queue.task_done()

# 创建并启动线程
threads = []
for _ in range(num_threads):
    thread = threading.Thread(target=worker, args=(ip_queue,))
    threads.append(thread)
    thread.start()



# 等待所有线程完成
for thread in threads:
    thread.join()

print("IP range ping completed.")

三、将ping成功的IP结果集,进行汇总统计

# 处理ping_results.txt,使之便于查看
from collections import defaultdict

# 辅助函数,用于确定IP的网段
def get_subnet(ip):
    return '.'.join(ip.split('.')[:3])

# ping_results.txt文件名
input_file = 'ping_results.txt'
ping_count = 'ping_count.txt'

def sumip(input_file, outputfile=None):
    if outputfile:
        with open(ping_count, 'w', encoding='utf-8') as f:
            f.write("#每个网段可ping通个数:网段,可ping通数量\n")
    # 用于存储每个网段IP数量的字典
    subnet_count = defaultdict(int)
    # 读取文件并统计每个网段的IP数量
    with open(input_file, 'r') as file:
        # 跳过文件开头的注释行
        next(file)
        for line in file:
            ip = line.strip()
            if ip:  # 确保跳过空行
                subnet = get_subnet(ip)
                subnet_count[subnet] += 1
    # 打印每个网段及其IP数量
    for subnet, count in subnet_count.items():
        print(f"网段 {subnet} 有: {count} 个可通IP")
        if outputfile:
            with open(ping_count, 'a', encoding='utf-8') as f:
                f.write(f"{subnet}, {count}\n")

if __name__ == "__main__":
    sumip(input_file, outputfile=True)

四、结论

(1)通过直接运行单线程或者多线程代码,会得到一个结果集ping_results.txt。这里记录了所有ping通的IP

(2)用步骤三,对ping_results.txt 中的IP段进行统计。得到文件ping_count.txt。即可得知每一个小IP段有多少台电脑处于联网状态

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值