📅  最后修改于: 2023-12-03 15:18:58.301000             🧑  作者: Mango
Ping是一种网络工具,用于测试网络连接。它发送一个小的数据包到网络上的另一台计算机上,并等待接收响应。在Python中,可以使用标准库中的socket和subprocess模块实现ping功能。
使用socket模块进行ping的步骤如下:
下面是一个例子:
import socket
import os
import struct
import time
def checksum(packet):
'''计算ICMP包的校验和'''
sum = 0
countTo = (len(packet) // 2) * 2
count = 0
while count < countTo:
thisVal = ord(packet[count + 1]) * 256 + ord(packet[count])
sum = sum + thisVal
sum = sum & 0xffffffff
count = count + 2
if countTo < len(packet):
sum = sum + ord(packet[len(packet) - 1])
sum = sum & 0xffffffff
sum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
answer = ~sum
answer = answer & 0xffff
answer = answer >> 8 | (answer << 8 & 0xff00)
return answer
def ping(host, count=4, timeout=2):
'''ping主机,返回每个ICMP包的延迟时间(单位:秒)'''
delay_sum = 0
delay_count = 0
# 创建ICMP套接字
icmp = socket.getprotobyname('icmp')
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
# 设置超时(秒)
sock.settimeout(timeout)
# 每个包的大小(字节)
packet_size = 56
# 发送指定数量的包
for i in range(count):
# 构造ICMP包(Echo请求)
packet_id = os.getpid() & 0xFFFF
packet_checksum = 0
packet_data = b'Q'*packet_size
packet_header = struct.pack('BBHHH', 8, 0, packet_checksum, packet_id, i)
packet_checksum = checksum(packet_header + packet_data)
packet_header = struct.pack('BBHHH', 8, 0, packet_checksum, packet_id, i)
packet = packet_header + packet_data
try:
# 记录发送时间
send_time = time.time()
# 发送ICMP包并等待响应
sock.sendto(packet, (host, 1))
reply, addr = sock.recvfrom(1024)
# 记录接收时间
recv_time = time.time()
# 计算延迟时间
delay = (recv_time - send_time) * 1000
# 输出结果
print('Reply from %s: bytes=%d time=%.1fms' % (addr[0], len(packet), delay))
# 统计延迟时间
delay_sum += delay
delay_count += 1
except socket.timeout:
# 输出超时结果
print('Request timeout')
# 关闭套接字
sock.close()
# 返回平均延迟时间
return delay_sum / delay_count if delay_count else None
使用方法如下:
delay = ping('192.168.0.1', count=4, timeout=2)
if delay is not None:
print('Average delay: %.1fms' % delay)
else:
print('Ping failed')
此处将ping次数设置为4次,并设置超时间为2秒。如果ping成功,会返回每个ICMP包的延迟时间的平均值(单位:毫秒);如果ping失败,会返回None。
使用subprocess模块进行ping的方法比较简单,只需调用操作系统的ping命令即可。下面是一个例子:
import subprocess
def ping(host, count=4, timeout=2):
'''ping主机,返回是否ping通'''
cmd = ['ping', '-c', str(count), '-W', str(timeout), host]
try:
# 运行ping命令并等待返回值
output = subprocess.check_output(cmd)
return True
except subprocess.CalledProcessError:
return False
使用方法同上,只是返回的不是延迟时间,而是是否ping通。如果ping通,返回True;否则返回False。
至此,我们分别介绍了使用socket和subprocess模块进行ping的方法。两种方法各有优劣,需要根据实际情况选择。无论哪种方法,都需要进行错误处理和超时设置,以保证程序的健壮性。