The example in this article describes how Python implements Ping. Share to everyone for your reference. Specific as follows:
#!/usr/bin/env python#coding:utf-8import OS, sys, socket, struct, select, time# from/usr/include/linux/icmp.h; Your milage may vary. Icmp_echo_request = 8 # seems to being the same on Solaris.def checksum (source_string): "" "I ' m not too confident is right but testing seems to suggest that it gives the same answers as in_cksum in ping.c "" "sum = 0 Countto = (len (source_string)/2) * * Count = 0 while Count
> + (sum & 0xffff) sum = sum + (sum >> +) answer = ~sum answer = answer & 0xFFFF # Swap bytes. Bugger me if I know why. Answer = Answer >> 8 | (Answer << 8 & 0xff00) return answerdef receive_one_ping (my_socket, ID, timeout): "" Receive the ping from T He socket. "" "TimeLeft = timeout while true:startedselect = Time.time () Whatready = Select.select ([My_socket], [], [], Time left) Howlonginselect = (Time.time ()-Startedselect) if whatready[0] = = []: # Timeout return timereceived = Time.time () recpacket, addr = My_socket.recvfrom (1024x768) Icmpheader = recpacket[20:28] Type, code, checksum, Packe TID, sequence = Struct.unpack ("Bbhhh", icmpheader) if Packetid = = Id:bytesindouble = Struct.calcsize ("D ") Timesent = Struct.unpack (" D ", recpacket[28:28 + bytesindouble]) [0] return timereceived-timesent timeLeft = Timeleft-howlonginselect if TimeLeft <= 0:returndef send_one_pING (My_socket, dest_addr, ID): "" "Send one ping to the given >dest_addr<. "" "Dest_addr = Socket.gethostbyname (dest_addr) # Header is type (8), Code (8), checksum (+), ID (+), sequence (+) m y_checksum = 0 # Make a dummy heder with a 0 checksum. Header = Struct.pack ("Bbhhh", Icmp_echo_request, 0, My_checksum, ID, 1) #压包 #a1 = Struct.unpack ("Bbhhh", header) #my test bytesindouble = Struct.calcsize ("d") data = (192-bytesindouble) * "Q" data = Struct.pack ("D", Time.time ()) + data # Calculate the checksum on the data and the dummy header. My_checksum = Checksum (header + data) # Now so we have the right checksum and we put that in. It ' s just easier # to make up a new header than to stuff it into the dummy. Header = Struct.pack ("Bbhhh", Icmp_echo_request, 0, Socket.htons (my_checksum), ID, 1) packet = header + Data My_socket.s EndTo (Packet, (DEST_ADDR, 1)) # Don ' t know about the 1def do_one (dest_addr, timeout): "" "Returns either the delay (in S Econds) or None on Timeout. "" "ICMP = Socket.getprotobyname (" ICMP ") Try:my_socket = Socket.socket (socket.af_inet, socket. Sock_raw, ICMP) except Socket.error, (errno, msg): if errno = = 1: # operation not permitted msg = msg + ( "-Note that ICMP messages can is sent from processes" "running as root." ) Raise Socket.error (msg) raise # Raise the original error my_id = Os.getpid () & 0xFFFF send_one_ping (MY_SOC Ket, DEST_ADDR, my_id) delay = receive_one_ping (my_socket, my_id, timeout) my_socket.close () return delaydef VERBOSE_PI Ng (dest_addr, timeout = 2, count = +): "" "Send >count< Ping to >dest_addr< with the given >timeout< and display the result. "" For I in Xrange (count): print "ping%s ..."% dest_addr, Try:delay = Do_one (dest_addr, timeout) except Socket.gaierror, E:print "failed. (Socket error: '%s ') "% e[1] break if delay = = None:print" failed. (timeout within%ssec.) " % TimeouT else:delay = delay * print "Get ping in%0.4fms"% delayif __name__ = = ' __main__ ': verbose_ping ("www .163.com ", 2, 1)
Hopefully this article will help you with Python programming.