您的位置:

udpping-一个简单的Python UDP ping工具

udpping-一个简单的Python UDP ping工具

更新:

一、介绍

在网络通信过程中,通过ping工具可以判断网络的连通性。但是使用ping命令进行测试的时候,需要等待远程主机的响应。而UDP ping工具udpping则不需要等待远程主机响应,只需要发送UDP数据包,判断是否发送成功或者超时。


udpping是一款基于Python编写的简单工具,用于测试目标主机的UDP响应率。

二、使用方法

1.环境

udpping可以运行在Python 2.7或Python 3.x环境中,无需安装其他依赖项。

2.命令行参数

udpping有三个命令行参数:

usage: udpping.py [-h] [-c COUNT] [-t TIMEOUT] target

其中:

  • * -h :查看帮助选项。
  • * -c :指定发送UDP数据包的数量,默认为4次。
  • * -t :设置超时时间,单位为秒,默认为1秒。
  • * target :指定要测试的目标主机。

3.示例

以下是测试本地主机的示例:

$ python udpping.py 127.0.0.1

输出:

Ping 127.0.0.1 with 16 bytes of data:
UDP packet sent
UDP packet sent
UDP packet sent
UDP packet sent

UDP 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

以下是测试百度主机的示例:

$ python udpping.py www.baidu.com

输出:

Ping www.baidu.com with 16 bytes of data:
UDP packet sent
UDP packet sent
UDP packet sent
UDP packet sent

UDP Ping statistics for www.baidu.com:
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

三、代码实现

1.发送UDP数据包

以下是发送UDP数据包的代码:

def send_udp_packet(dest_ip, dest_port):
    """
    发送UDP数据包
    """
    socket_obj = socket(AF_INET, SOCK_DGRAM)
    try:
        socket_obj.sendto(b'', (dest_ip, dest_port))
        return True
    except:
        return False
    finally:
        socket_obj.close()

2.计算UDP延迟时间

以下是计算UDP延迟时间的代码:

def calc_udp_delay_time(dest_ip, dest_port, timeout):
    """
    计算UDP延迟时间
    """
    send_time = time()
    recv_socket = socket(AF_INET, SOCK_DGRAM)
    recv_socket.bind(('', dest_port))
    recv_socket.settimeout(timeout)
    try:
        recv_socket.recvfrom(1024)
    except:
        return None
    finally:
        recv_socket.close()
    return (time() - send_time) * 1000

3.主函数

以下是主函数的代码:

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('target', help='Target IP or hostname')
    parser.add_argument('-c', metavar='COUNT', type=int, default=4,
                        help='Number of packets to send (default 4)')
    parser.add_argument('-t', metavar='TIMEOUT', type=float, default=1,
                        help='Timeout in seconds (default 1)')
    args = parser.parse_args()

    ipaddr = gethostbyname(args.target)
    packets_sent = 0
    packets_recv = 0
    min_delay = 99999
    max_delay = 0
    tot_delay = 0

    for i in range(args.c):
        # 发送数据包
        if send_udp_packet(ipaddr, 33434):
            packets_sent += 1

        # 计算延时时间
        delay_time = calc_udp_delay_time(ipaddr, 33434, args.t)
        if delay_time is not None:
            packets_recv += 1
            if delay_time < min_delay:
                min_delay = delay_time
            if delay_time > max_delay:
                max_delay = delay_time
            tot_delay += delay_time

        # 等待1秒钟
        sleep(1)

    print("Ping {} with 16 bytes of data:".format(args.target))
    print("")
    print("UDP Ping statistics for {}:".format(args.target))
    print("    Packets: Sent = {}, Received = {}, Lost = {} ({}% loss),".format(
        packets_sent, packets_recv, packets_sent - packets_recv,
        (packets_sent - packets_recv) * 100 // packets_sent if packets_sent > 0 else 0))
    if packets_recv > 0:
        print("Approximate round trip times in milli-seconds:")
        print("    Minimum = {0}ms, Maximum = {1}ms, Average = {2:.0f}ms".format(
            min_delay, max_delay, tot_delay / packets_recv))
    else:
        print("No response from the host.")