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程序设计有所帮助。