Recently, the company's network is not very powerful, resulting in occasional phone clicks. Our first response is to check the server. The answer is that the ping value is always too large, and it is not good to reply to colleagues, wait a moment.
This leads to a problem: if a colleague can make his own judgment, he can avoid frequent "disturbing" us.
The answer is: automatically display it in the background, so that colleagues can check it.
Based on a simple understanding of python in the past, Google ping python implementation, combined with web. py, very simple implementation of the function, the source code is as follows:
# Coding: UTF-8
"""
Web. py + ping
Www.591rmb.info
Ex:
# Nohup web_ping.py 9999 &
# Curl http: // 192.168.1.36: 9999/192. 168.1.86
Ping Code, Copy from the following website:
Http://www.g-loaded.eu/2009/10/30/python-ping/
"""
Import socket, select, time, web, urllib
Import OS, sys, socket, struct, select, time
Urls = (
'/(. *)', 'Ping'
)
App = web. application (urls, globals ())
Class Ping:
Def GET (self, ip ):
Return verbose_ping (ip, 2, 1)
# From/usr/include/linux/icmp. h; your milage may vary.
ICMP_ECHO_REQUEST = 8 # Seems to be the same on Solaris.
Def checksum (source_string ):
"""
I'm not too confident that this is right but testing seems
To suggest that it gives the same answers as in_cksum in ping. c
"""
Sum = 0
Countid = (len (source_string)/2) * 2
Count = 0
While count <countid:
ThisVal = ord (source_string [count + 1]) * 256 + ord (source_string [count])
Sum = sum + thisVal
Sum = sum & 0 xffffffff # Necessary?
Count = count + 2
If countTo <len (source_string ):
Sum = sum + ord (source_string [len (source_string)-1])
Sum = sum & 0 xffffffff # Necessary?
Sum = (sum> 16) + (sum & 0 xffff)
Sum = sum + (sum> 16)
Answer = ~ Sum
Answer = answer & 0 xffff
# Swap bytes. Bugger me if I know why.
Answer = answer> 8 | (answer <8 & 0xff00)
Return answer
Def receive_one_ping (my_socket, ID, timeout ):
"""
Receive the ping from the socket.
"""
TimeLeft = timeout
While True:
StartedSelect = time. time ()
WhatReady = select. select ([my_socket], [], [], timeLeft)
HowLongInSelect = (time. time ()-startedSelect)
If whatReady [0] = []: # Timeout
Return
TimeReceived = time. time ()
RecPacket, addr = my_socket.recvfrom (1024)
IcmpHeader = recPacket [20: 28]
Type, code, checksum, packetID, 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:
Return
Def 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 (16), id (16), sequence (16)
My_checksum = 0
# Make a dummy heder with a 0 checksum.
Header = struct. pack ("bbHHh", ICMP_ECHO_REQUEST, 0, my_checksum, ID, 1)
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 that we have the right checksum, 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.sendto (packet, (dest_addr, 1) # Don't know about the 1
Def do_one (dest_addr, timeout ):
"""
Returns either the delay (in seconds) or none on timeout.
"""
Icmp = socket. getprotobyname ("icmp ")
Try:
My_socket = socket. socket (socket. AF_INET, socket. SOCK_RAW, icmp)
Failed t socket. error, (errno, msg ):
If errno = 1:
# Operation not permitted
Msg = msg + (
"-Note that ICMP messages can only be sent from processes"
"Running as root ."
)
Raise socket. error (msg)
Raise # raise the original error
My_ID = OS. getpid () & 0 xFFFF
Send_one_ping (my_socket, dest_addr, my_ID)
Delay = receive_one_ping (my_socket, my_ID, timeout)
My_socket.close ()
Return delay
Def verbose_ping (dest_addr, timeout = 2, count = 4 ):
"""
Send> count <ping to> dest_addr <with the given> timeout <and display
The result.
"""
Result =''
For I in xrange (count ):
Result = "ping" + dest_addr
Try:
Delay = do_one (dest_addr, timeout)
Handle t socket. gaierror, e:
Result + = "failed. (socket error: '% s')" % e [1]
Break
If delay = None:
Result + = "failed. (timeout within % ssec.)" % timeout
Else:
Delay = delay * 1000
Result + = "=> % dms" % delay
Return result
If _ name _ = "_ main __":
Def void (s): pass
App. run ()
From python.cn