1. #coding:utf-8
  2. #!/usr/bin/env python
  3.  
  4. import os
  5. import argparse
  6. import socket
  7. import struct
  8. import select
  9. import time
  10.  
  11. #
  12. ICMP_ECHO_REQUEST = 8 # Platform specific
  13. #超时时间
  14. DEFAULT_TIMEOUT = 2
  15. #ping到次数
  16. DEFAULT_COUNT = 4
  17.  
  18. class Pinger(object):
  19. """ Pings to a host -- the Pythonic way"""
  20.  
  21. def __init__(self, target_host, count=DEFAULT_COUNT, timeout=DEFAULT_TIMEOUT):
  22. '''
  23.  
  24. :param target_host: 目标主机
  25. :param count: ping的次数
  26. :param timeout: 超时时间
  27. :return:
  28. '''
  29. self.target_host = target_host
  30. self.count = count
  31. self.timeout = timeout
  32.  
  33. def do_checksum(self, source_string):
  34. """ 验证包的完整性 """
  35. sum = 0
  36. #不小于长度的最小偶数
  37. max_count = (len(source_string)/2)*2
  38. count = 0
  39. while count < max_count:
  40. val = ord(source_string[count + 1])*256 + ord(source_string[count])
  41. sum = sum + val
  42. sum = sum & 0xffffffff
  43. count = count + 2
  44.  
  45. if max_count<len(source_string):
  46. sum = sum + ord(source_string[len(source_string) - 1])
  47. sum = sum & 0xffffffff
  48.  
  49. sum = (sum >> 16) + (sum & 0xffff)
  50. sum = sum + (sum >> 16)
  51. answer = ~sum
  52. answer = answer & 0xffff
  53. answer = answer >> 8 | (answer << 8 & 0xff00)
  54. return answer
  55.  
  56. def receive_pong(self, sock, ID, timeout):
  57. """
  58. 接受ping的返回值.
  59. """
  60. time_remaining = timeout
  61. while True:
  62. start_time = time.time()
  63. readable = select.select([sock], [], [], time_remaining)
  64. time_spent = (time.time() - start_time)
  65. if readable[0] == []: # Timeout
  66. return
  67.  
  68. time_received = time.time()
  69. recv_packet, addr = sock.recvfrom(1024)
  70. icmp_header = recv_packet[20:28]
  71. type, code, checksum, packet_ID, sequence = struct.unpack(
  72. "bbHHh", icmp_header
  73. )
  74. if packet_ID == ID:
  75. bytes_In_double = struct.calcsize("d")
  76. time_sent = struct.unpack("d", recv_packet[28:28 + bytes_In_double])[0]
  77. return time_received - time_sent
  78.  
  79. time_remaining = time_remaining - time_spent
  80. if time_remaining <= 0:
  81. return
  82.  
  83. def send_ping(self, sock, ID):
  84. """
  85. 发送ping到目标主机
  86. """
  87. target_addr = socket.gethostbyname(self.target_host)
  88. my_checksum = 0
  89. # Create a dummy heder with a 0 checksum.
  90. header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, my_checksum, ID, 1)
  91. bytes_In_double = struct.calcsize("d")
  92. data = (192 - bytes_In_double) * "Q"
  93. data = struct.pack("d", time.time()) + data
  94.  
  95. # Get the checksum on the data and the dummy header.
  96. my_checksum = self.do_checksum(header + data)
  97. header = struct.pack(
  98. "bbHHh", ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), ID, 1
  99. )
  100. packet = header + data
  101. sock.sendto(packet, (target_addr, 1))
  102.  
  103. def ping_once(self):
  104. """
  105. Returns the delay (in seconds) or none on timeout.
  106. """
  107. icmp = socket.getprotobyname("icmp")
  108. try:
  109. sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
  110. except socket.error, (errno, msg):
  111. if errno == 1:
  112. # Not superuser, so operation not permitted
  113. msg += "ICMP messages 只能由root进程发起"
  114. raise socket.error(msg)
  115. except Exception, e:
  116. print "Exception: %s" %(e)
  117.  
  118. my_ID = os.getpid() & 0xFFFF
  119. self.send_ping(sock, my_ID)
  120. delay = self.receive_pong(sock, my_ID, self.timeout)
  121. sock.close()
  122. return delay
  123.  
  124. def ping(self):
  125. """
  126. Run the ping process
  127. """
  128. for i in xrange(self.count):
  129. print "Ping to %s..." % self.target_host,
  130. try:
  131. delay = self.ping_once()
  132. except socket.gaierror, e:
  133. print "Ping failed. (socket error: '%s')" % e[1]
  134. break
  135.  
  136. if delay == None:
  137. print "Ping failed. (timeout within %ssec.)" % self.timeout
  138. else:
  139. delay = delay * 1000
  140. print "Get pong in %0.4fms" % delay
  141.  
  142. if __name__ == '__main__':
  143. parser = argparse.ArgumentParser(description='Python ping')
  144. parser.add_argument('--target-host', action="store", dest="target_host", required=True)
  145. given_args = parser.parse_args()
  146. target_host = given_args.target_host
  147. pinger = Pinger(target_host=target_host)
  148. pinger.ping()

使用ICMP协议Ping网络主机的更多相关文章

  1. ICMP协议Ping命令的应用

    ICMP的全称是 Internet Control Message Protocol ,它是TCP/IP协议族的一个子协议,属于网络层协议,用于在IP主机.路由器之间传递控制消息.从技术角度来讲,就是 ...

  2. 计网-ping服务命令与ICMP协议

    目录 一.IP协议的助手 —— ICMP 协议(网络层协议) 二.ping —— 查询报文类型的使用 三.traceroute —— 差错报文类型的使用 参考:从Wireshark抓包软件角度理解PI ...

  3. IP协议的助手 —— ICMP 协议

    IP协议的助手 —— ICMP 协议 IP协议的助手 —— ICMP 协议 ping 是基于 ICMP 协议工作的,所以要明白 ping 的工作,首先我们先来熟悉 ICMP 协议. ICMP 是什么? ...

  4. UNIX网络编程——利用ARP和ICMP协议解释ping命令

    一.MTU 以太网和IEEE 802.3对数据帧的长度都有限制,其最大值分别是1500和1492字节,将这个限制称作最大传输单元(MTU,Maximum Transmission Unit)      ...

  5. 网络协议 5 - ICMP 与 ping:投石问路的侦察兵

        日常开发中,我们经常会碰到查询网络是否畅通以及域名对应 IP 地址等小需求,这时候用的最多的应该就是 ping 命令了. 那你知道 ping 命令是怎么工作的吗?今天,我们就来一起认识下 pi ...

  6. 【网络协议】ICMP协议、Ping、Traceroute

        ICMP协议 ICMP常常被觉得是IP层的一个组成部分,它是网络层的一个协议.它传递差错报文以及其它须要注意的信息.ICMP报文通常被IP层或更高层(TCP.UDP等)使用,它是在IP数据报内 ...

  7. 网络协议 5 - ICMP 与 Ping

    日常开发中,我们经常会碰到查询网络是否畅通以及域名对应 IP 地址等小需求,这时候用的最多的应该就是 ping 命令了. 那你知道 ping 命令是怎么工作的吗?今天,我们就来一起认识下 ping 命 ...

  8. Linux用ICMP协议实现简单Ping网络监测功能

    ICMP是(Internet Control Message Protocol)Internet控制报文协议.它是TCP/IP协议族的一个子协议,用于在IP主机.路由器之间传递控制消息.控制消息是指网 ...

  9. 网络协议学习笔记(二)物理层到MAC层,交换机和VLAN,ICMP与ping原理

    概述 之前网络学习笔记主要讲解了IP的诞生,或者说整个操作系统的诞生,一旦有了IP,就可以在网络的环境里和其他的机器展开沟通了.现在开始给大家讲解关于网络底层的相关知识. 从物理层到MAC层:如何在宿 ...

随机推荐

  1. Python学习笔记-Day3-set集合操作

    set集合,是一个无序且不重复的元素集合.定义方式类似字典使用{}创建 目前我们学过的数据类型: 1.字符串(str),2.整型(int),3.浮点型(float),4,列表(list) 5.元组(t ...

  2. ThreadLocal深入理解一

    转载:http://www.cnblogs.com/dolphin0520/p/3920407.html 想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使 ...

  3. PowerShell处理RSS信息

    转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 环境:Windows Server 2012 EN(解决PowerShell控制台中文乱码问题:方 ...

  4. 【SQL】SQL中笛卡尔积、内连接、外连接的数据演示

    SQL的查询语句中,常使用到内连接.外连接,以及连接的基础--笛卡尔积运算. 在简单的SQL中,也许我们还分辨清楚数据如何连接,一旦查询复杂了,脑子也犯浆糊了,迷迷糊糊的. 本文,简单以数据形式记录连 ...

  5. css基本知识

    WANGJUN59451   css基本知识 1.CSS 简介 CSS 指层叠样式表 (Cascading Style Sheets),是一种用来表现 HTML 文档样式的语言,样式定义如何显示 HT ...

  6. Eclipse搭建Android5.0应用开发环境 “ndk-build”:launchingfailed问题解决

    Eclipse搭建Android5.0应用开发环境 "ndk-build":launchingfailed问题解决 详细参考http://blog.csdn.net/loongem ...

  7. (1)建立一个名叫Cat的类: 属性:姓名、毛色、年龄 行为:显示姓名、喊叫 (2)编写主类: 创建一个对象猫,姓名为“妮妮”,毛色为“灰色”,年龄为2岁,在屏幕上输 出该对象的毛色和年龄,让该对象调用显示姓名和喊叫两个方法。

    package lianxi; public class Cat { String Name, Color; int Age; void getName() { System.out.println( ...

  8. 【Unity3D游戏开发】基础知识之Tags和Layers (三二)[转]

    Tags和Layers分别表示是Unity引擎里面的标签和层,他们都是用来对GameObject进行标识的属性,Tags常用于单个GameObject,Layers常用于一组的GameObject.添 ...

  9. require或include相对路径多层嵌套引发的问题

    require或include相对路径多层嵌套引发的问题   php中require/include 包含相对路径的解决办法 在PHP中require,include一个文件时,大都是用相对路径,是个 ...

  10. XML学习笔记(二)-- DTD格式规范

    标签(空格分隔): 学习笔记 XML的一个主要目的是允许应用程序之间自由交换结构化的数据,因此要求XML文档具有一致的结构.业务逻辑和规则.可以定义一种模式来定义XML文档的结构,并借此验证XML文档 ...