python網路作業:使用python的socket庫實現ICMP協議的ping
ofollow,noindex">python測試開發專案實戰-目錄
ICMP ping是您遇到過的最常見的網路掃描型別。 開啟命令列提示符或終端並輸入pingwww.google.com 非常容易。
為什麼要在python中實現?
- 很多名牌大學喜歡考試用python的socket庫實現ICMP協議的ping
- 個別環境沒有ping
直接上程式碼:
#!/usr/bin/python3 # -*- coding: utf-8 -*- # 技術支援:https://www.jianshu.com/u/69f40328d4f0 # 技術支援 https://china-testing.github.io/ # https://github.com/china-testing/python-api-tesing/blob/master/practices/ping.py # 討論釘釘免費群21745728 qq群144081101 567351477 # CreateDate: 2018-11-22 import os import argparse import socket import struct import select import time ICMP_ECHO_REQUEST = 8 # Platform specific DEFAULT_TIMEOUT = 2 DEFAULT_COUNT = 4 class Pinger(object): """ Pings to a host -- the Pythonic way""" def __init__(self, target_host, count=DEFAULT_COUNT, timeout=DEFAULT_TIMEOUT): self.target_host = target_host self.count = count self.timeout = timeout def do_checksum(self, source_string): """Verify the packet integritity """ sum = 0 max_count = (len(source_string)/2)*2 count = 0 while count < max_count: val = source_string[count + 1]*256 + source_string[count] sum = sum + val sum = sum & 0xffffffff count = count + 2 if max_count<len(source_string): sum = sum + ord(source_string[len(source_string) - 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 receive_pong(self, sock, ID, timeout): """ Receive ping from the socket. """ time_remaining = timeout while True: start_time = time.time() readable = select.select([sock], [], [], time_remaining) time_spent = (time.time() - start_time) if readable[0] == []: # Timeout return time_received = time.time() recv_packet, addr = sock.recvfrom(1024) icmp_header = recv_packet[20:28] type, code, checksum, packet_ID, sequence = struct.unpack( "bbHHh", icmp_header ) if packet_ID == ID: bytes_In_double = struct.calcsize("d") time_sent = struct.unpack("d", recv_packet[28:28 + bytes_In_double])[0] return time_received - time_sent time_remaining = time_remaining - time_spent if time_remaining <= 0: return def send_ping(self, sock,ID): """ Send ping to the target host """ target_addr=socket.gethostbyname(self.target_host) my_checksum = 0 # Create a dummy heder with a 0 checksum. header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, my_checksum, ID, 1) bytes_In_double = struct.calcsize("d") data = (192 - bytes_In_double) * "Q" data = struct.pack("d", time.time()) + bytes(data.encode('utf-8')) # Get the checksum on the data and the dummy header. my_checksum = self.do_checksum(header + data) header = struct.pack( "bbHHh", ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), ID, 1 ) packet = header + data sock.sendto(packet, (target_addr, 1)) def ping_once(self): """ Returns the delay (in seconds) or none on timeout. """ icmp = socket.getprotobyname("icmp") try: sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp) except socket.error as e: if e.errno == 1: # Not superuser, so operation not permitted e.msg +="ICMP messages can only be sent from root user processes" raise socket.error(e.msg) except Exception as e: print ("Exception: %s" %(e)) my_ID = os.getpid() & 0xFFFF self.send_ping(sock, my_ID) delay = self.receive_pong(sock, my_ID, self.timeout) sock.close() return delay def ping(self): """ Run the ping process """ for i in range(self.count): print ("Ping to %s..." % self.target_host,) try: delay=self.ping_once() except socket.gaierror as e: print ("Ping failed. (socket error: '%s')" % e[1]) break if delay==None: print ("Ping failed. (timeout within %ssec.)" % self.timeout) else: delay=delay * 1000 print ("Get pong in %0.4fms" % delay) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Python ping') parser.add_argument('host', action="store", help=u'主機名') given_args = parser.parse_args() target_host = given_args.host pinger = Pinger(target_host=target_host) pinger.ping()
參考資料
- 本文最新版本地址
- 討論qq群144081101 567351477
- 本文涉及的python測試開發庫 謝謝點贊!
- 本文相關海量書籍下載
- python 3.7極速入門教程9最佳python中文工具書籍下載
- 最新程式碼地址
執行
注意要有root或管理員許可權:
# python3 ping.py china-testing.github.io Ping to china-testing.github.io... Get pong in 160.7175ms Ping to china-testing.github.io... Get pong in 160.8465ms Ping to china-testing.github.io... Get pong in 12.0983ms Ping to china-testing.github.io... Get pong in 161.3324ms # python3 ping.py www.so.com Ping to www.so.com... Get pong in 29.0303ms Ping to www.so.com... Get pong in 28.8599ms Ping to www.so.com... Get pong in 28.9860ms Ping to www.so.com... Get pong in 29.0167ms