python ping模块_python 实现ping

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92#coding:utf-8

import socket

import struct

import time

import os

import select

ICMP_ECHO_REQUEST=8

'''

校验和

在ip中只校验20字节的ip报头

icmp 校验 校验整个报文(报头加上数据)

校验和计算:

发送数据时;

1 把校验和字段设置为0

2 把需要校验的数据看成16位为单位的数字 依次进行二进制反码求和

3 得到结果

'''

def checksum(source_string):

sum = 0

countTo = (len(source_string)/2)*2

#首先计算字符串的长度

count = 0

while count

thisVal = ord(source_string[count + 1])*256 + ord(source_string[count])

sum = sum + thisVal

sum = sum & 0xffffffff

count = count + 2

if countTo

sum = sum + ord(source_string[len(source_string) - 1])

sum = sum & 0xffffffff

sum = (sum >> 16)  +  (sum & 0xffff)

sum = sum + (sum >> 16)

answer = ~sum

answer = answer & 0xffff

answer = answer >> 8 | (answer << 8 & 0xff00)

return answer

def send_ping(my_socket,dest_addr,id):

header= struct.pack("bbHHh",8,0,0,id,1)

#构造一个空的头

webtime=struct.pack("d",time.time()

#增加发送时间戳 作为icmp的data

'''

关于计算目的主机和源主机数据传送的时间: echo-request 构造的数据包中添加时间戳,

echo-reply 返回数据 解包后得到time  计算时间差

'''

data=webtime

chksum=checksum(header+data)

#icmp 的检验和是检验头部和数据域的 区别与ip检验和

header= struct.pack("bbHHh", 8, 0, socket.htons(chksum),id, 1)

#把16位正整数从主机字节序转换成网络序 socket.htons()

#1>Unix系统在实现ping程序时把ICMP报文中的标识符字段置成发送进程的ID号。这样即使在同一台主机上同时运行了多个ping程序实例,ping程序也可以识别出返回的信息。

#2>序列号从0开始,每发送一次新的回显请求就加1。ping程序打印出返回的每个分组的序列号,允许我们查看是否有分组丢失,失序或重复。.

packet=header+data

my_socket.sendto(packet,(dest_addr,1))

#socket.sendto(string, address)

def recive_ping(my_socket,id,timeout):

timeleft=timeout

while True:

startedselect=time.time();

#select.select(rlist, wlist, xlist[, timeout])

whatnow=select.select([my_socket],[],[],timeleft)

time_select=(time.time()-startedselect)

if whatnow[0] ==[]:

return

time_receive=time.time()

recvpacket,addr=my_socket.recvfrom(1024)

icmpheader=recvpacket[20:28]

#一个ICMP报文包括IP头部(20字节)、ICMP头部(8字节)前20个字节是ip头部

type,code,checknum,ID,sequence=struct.unpack("bbHHh",icmpheader)

if ID==id:

time_sent=struct.unpack("d",recvpacket[28:])[0]

return  time_receive-time_sent

time_out=timeleft-time_select

if time_out>=0:

return

def do(dest_addr,timeout=2):

icmp=socket.getprotobyname("icmp")

s= socket.socket(socket.AF_INET, socket.SOCK_RAW,icmp)

id=os.getpid()

send_ping(s,dest_addr,id)

delay=recive_ping(s,id,timeout)

print  " get ping in %0.4fms"%delay

if __name__=='__main__':

do('192.168.1.1')

[p=30, 2, left]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值