You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用asyncio实现局域网在线主机检测报错:期望协程却得到True

问题分析与修正方案

错误原因

你调用asyncio.create_task()时传入的是普通函数的执行结果(pinger(ip)会立即执行并返回True或None),但create_task要求传入的是协程对象(用async def定义的函数调用后返回的对象),这直接触发了TypeError。

另外,原代码里的subprocess.check_call是同步阻塞调用,就算改成协程,也会卡住整个asyncio事件循环,完全发挥不了异步的优势。

修正后的代码

#!/usr/bin/env python3
import asyncio
import socket
import subprocess

def get_my_ip():
    """获取本机IP,生成局域网网段前缀"""
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # 连接公共DNS,确保能获取本机正确IP
        s.connect(("8.8.8.8", 80))
        ip = s.getsockname()[0]
        print(f"My ip is: {ip}")
        return ip
    finally:
        s.close()

async def pinger(ip):
    """异步执行ping检测,返回存活IP"""
    try:
        # 使用asyncio异步子进程,避免阻塞事件循环
        proc = await asyncio.create_subprocess_exec(
            'ping', '-c1', '-W1',  # -W1设置超时1秒,加快检测速度
            ip,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL
        )
        await proc.wait()
        if proc.returncode == 0:
            print(f"✅ {ip} 存活")
            return ip
    except Exception:
        pass
    return None

async def main():
    pool_size = 255
    start = 102
    # 生成局域网网段前缀,比如192.168.1.
    ip_parts = get_my_ip().split('.')
    base_ip = '.'.join(ip_parts[:3]) + '.'

    # 创建所有ping任务
    tasks = [pinger(f"{base_ip}{i}") for i in range(start, pool_size+1)]
    # 等待所有任务完成,过滤掉None(即未存活的IP)
    alive_ips = [ip for ip in await asyncio.gather(*tasks) if ip]

    print("\n=== 存活主机列表 ===")
    for ip in alive_ips:
        print(ip)

if __name__ == "__main__":
    asyncio.run(main())

关键改动说明

  • 把pinger改成async def定义的协程函数,调用后返回协程对象,符合asyncio的要求(asyncio.gather可直接接收协程对象,无需手动调用create_task)。
  • 替换同步的subprocess.check_call为异步的asyncio.create_subprocess_exec,配合await proc.wait()让ping操作在后台执行,不阻塞其他任务。
  • 给ping命令增加-W1参数设置超时1秒,大幅提升检测效率。
  • 使用subprocess.DEVNULL替代手动打开/dev/null,更简洁安全。
  • 收集并过滤出所有存活的IP,让结果更直观。

内容的提问来源于stack exchange,提问作者Ciasto piekarz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:32:10