python实现ping的方法
本文实例讲述了python实现ping的方法。分享给大家供大家参考。具体如下:
#!/usr/bin/envpython
#coding:utf-8
importos,sys,socket,struct,select,time
#From/usr/include/linux/icmp.h;yourmilagemayvary.
ICMP_ECHO_REQUEST=8#SeemstobethesameonSolaris.
defchecksum(source_string):
"""
I'mnottooconfidentthatthisisrightbuttestingseems
tosuggestthatitgivesthesameanswersasin_cksuminping.c
"""
sum=0
countTo=(len(source_string)/2)*2
count=0
whilecount<countTo:
thisVal=ord(source_string[count+1])*256+ord(source_string[count])
sum=sum+thisVal
sum=sum&0xffffffff#Necessary?
count=count+2
ifcountTo<len(source_string):
sum=sum+ord(source_string[len(source_string)-1])
sum=sum&0xffffffff#Necessary?
sum=(sum>>16)+(sum&0xffff)
sum=sum+(sum>>16)
answer=~sum
answer=answer&0xffff
#Swapbytes.BuggermeifIknowwhy.
answer=answer>>8|(answer<<8&0xff00)
returnanswer
defreceive_one_ping(my_socket,ID,timeout):
"""
receivethepingfromthesocket.
"""
timeLeft=timeout
whileTrue:
startedSelect=time.time()
whatReady=select.select([my_socket],[],[],timeLeft)
howLongInSelect=(time.time()-startedSelect)
ifwhatReady[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
)
ifpacketID==ID:
bytesInDouble=struct.calcsize("d")
timeSent=struct.unpack("d",recPacket[28:28+bytesInDouble])[0]
returntimeReceived-timeSent
timeLeft=timeLeft-howLongInSelect
iftimeLeft<=0:
return
defsend_one_ping(my_socket,dest_addr,ID):
"""
Sendonepingtothegiven>dest_addr<.
"""
dest_addr=socket.gethostbyname(dest_addr)
#Headeristype(8),code(8),checksum(16),id(16),sequence(16)
my_checksum=0
#Makeadummyhederwitha0checksum.
header=struct.pack("bbHHh",ICMP_ECHO_REQUEST,0,my_checksum,ID,1)#压包
#a1=struct.unpack("bbHHh",header)#mytest
bytesInDouble=struct.calcsize("d")
data=(192-bytesInDouble)*"Q"
data=struct.pack("d",time.time())+data
#Calculatethechecksumonthedataandthedummyheader.
my_checksum=checksum(header+data)
#Nowthatwehavetherightchecksum,weputthatin.It'sjusteasier
#tomakeupanewheaderthantostuffitintothedummy.
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'tknowaboutthe1
defdo_one(dest_addr,timeout):
"""
Returnseitherthedelay(inseconds)ornoneontimeout.
"""
icmp=socket.getprotobyname("icmp")
try:
my_socket=socket.socket(socket.AF_INET,socket.SOCK_RAW,icmp)
exceptsocket.error,(errno,msg):
iferrno==1:
#Operationnotpermitted
msg=msg+(
"-NotethatICMPmessagescanonlybesentfromprocesses"
"runningasroot."
)
raisesocket.error(msg)
raise#raisetheoriginalerror
my_ID=os.getpid()&0xFFFF
send_one_ping(my_socket,dest_addr,my_ID)
delay=receive_one_ping(my_socket,my_ID,timeout)
my_socket.close()
returndelay
defverbose_ping(dest_addr,timeout=2,count=100):
"""
Send>count<pingto>dest_addr<withthegiven>timeout<anddisplay
theresult.
"""
foriinxrange(count):
print"ping%s..."%dest_addr,
try:
delay=do_one(dest_addr,timeout)
exceptsocket.gaierror,e:
print"failed.(socketerror:'%s')"%e[1]
break
ifdelay==None:
print"failed.(timeoutwithin%ssec.)"%timeout
else:
delay=delay*1000
print"getpingin%0.4fms"%delay
if__name__=='__main__':
verbose_ping("www.163.com",2,1)
希望本文所述对大家的Python程序设计有所帮助。