Ping function implemented by python (web. py)

Source: Internet
Author: User
Tags socket error

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.