Python中是否有现成的库可以发送ICMP报文并获取RTT数据?

RT。


Python中是否有现成的库可以发送ICMP报文并获取RTT数据?
3 回复

有,标准库里的 socket 就能直接发ICMP报文收回复,算RTT。不过得自己构造ICMP头,有点麻烦。我一般用 ping3 或者 pythonping 这两个第三方库,省事儿。

1. 用 ping3 (最简单)

import ping3

rtt = ping3.ping('example.com')  # 返回RTT,单位秒,超时返回None或False
print(f"RTT: {rtt} seconds")

安装:pip install ping3

2. 用 pythonping (功能更全)

from pythonping import ping

result = ping('example.com', count=4)  # 发4个包
print(result.rtt_avg_ms)  # 平均RTT
print(result)  # 看详细结果

安装:pip install pythonping

3. 自己用 socket 撸 (理解原理) 下面这个例子发一个ICMP Echo Request,然后收回复计算时间:

import socket
import struct
import time
import select

def ping(host, timeout=2):
    try:
        dest_addr = socket.gethostbyname(host)
    except socket.gaierror:
        return None

    # 创建原始套接字
    icmp = socket.getprotobyname("icmp")
    sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
    sock.settimeout(timeout)

    # 构造ICMP包 (Type 8, Code 0 - Echo Request)
    header = struct.pack("!BBHHH", 8, 0, 0, 1, 1)
    data = b"PING_TEST"
    checksum = 0  # 简化,实际需要计算校验和
    packet = header + data

    start = time.time()
    sock.sendto(packet, (dest_addr, 0))

    # 等回复
    ready = select.select([sock], [], [], timeout)
    if ready[0]:
        recv_packet, addr = sock.recvfrom(1024)
        rtt = (time.time() - start) * 1000  # 转毫秒
        sock.close()
        return rtt
    sock.close()
    return None

print(ping("example.com"))

总结:直接装 ping3 最省心。


回到顶部