#coding:utf-8
#!/usr/bin/env python import os
import argparse
import socket
import struct
import select
import time #
ICMP_ECHO_REQUEST = 8 # Platform specific
#超时时间
DEFAULT_TIMEOUT = 2
#ping到次数
DEFAULT_COUNT = 4 class Pinger(object):
""" Pings to a host -- the Pythonic way""" def __init__(self, target_host, count=DEFAULT_COUNT, timeout=DEFAULT_TIMEOUT):
''' :param target_host: 目标主机
:param count: ping的次数
:param timeout: 超时时间
:return:
'''
self.target_host = target_host
self.count = count
self.timeout = timeout def do_checksum(self, source_string):
""" 验证包的完整性 """
sum = 0
#不小于长度的最小偶数
max_count = (len(source_string)/2)*2
count = 0
while count < max_count:
val = ord(source_string[count + 1])*256 + ord(source_string[count])
sum = sum + val
sum = sum & 0xffffffff
count = count + 2 if max_count<len(source_string):
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 receive_pong(self, sock, ID, timeout):
"""
接受ping的返回值.
"""
time_remaining = timeout
while True:
start_time = time.time()
readable = select.select([sock], [], [], time_remaining)
time_spent = (time.time() - start_time)
if readable[0] == []: # Timeout
return time_received = time.time()
recv_packet, addr = sock.recvfrom(1024)
icmp_header = recv_packet[20:28]
type, code, checksum, packet_ID, sequence = struct.unpack(
"bbHHh", icmp_header
)
if packet_ID == ID:
bytes_In_double = struct.calcsize("d")
time_sent = struct.unpack("d", recv_packet[28:28 + bytes_In_double])[0]
return time_received - time_sent time_remaining = time_remaining - time_spent
if time_remaining <= 0:
return def send_ping(self, sock, ID):
"""
发送ping到目标主机
"""
target_addr = socket.gethostbyname(self.target_host)
my_checksum = 0
# Create a dummy heder with a 0 checksum.
header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, my_checksum, ID, 1)
bytes_In_double = struct.calcsize("d")
data = (192 - bytes_In_double) * "Q"
data = struct.pack("d", time.time()) + data # Get the checksum on the data and the dummy header.
my_checksum = self.do_checksum(header + data)
header = struct.pack(
"bbHHh", ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), ID, 1
)
packet = header + data
sock.sendto(packet, (target_addr, 1)) def ping_once(self):
"""
Returns the delay (in seconds) or none on timeout.
"""
icmp = socket.getprotobyname("icmp")
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
except socket.error, (errno, msg):
if errno == 1:
# Not superuser, so operation not permitted
msg += "ICMP messages 只能由root进程发起"
raise socket.error(msg)
except Exception, e:
print "Exception: %s" %(e) my_ID = os.getpid() & 0xFFFF
self.send_ping(sock, my_ID)
delay = self.receive_pong(sock, my_ID, self.timeout)
sock.close()
return delay def ping(self):
"""
Run the ping process
"""
for i in xrange(self.count):
print "Ping to %s..." % self.target_host,
try:
delay = self.ping_once()
except socket.gaierror, e:
print "Ping failed. (socket error: '%s')" % e[1]
break if delay == None:
print "Ping failed. (timeout within %ssec.)" % self.timeout
else:
delay = delay * 1000
print "Get pong in %0.4fms" % delay if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Python ping')
parser.add_argument('--target-host', action="store", dest="target_host", required=True)
given_args = parser.parse_args()
target_host = given_args.target_host
pinger = Pinger(target_host=target_host)
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. Spring中DispacherServlet、WebApplicationContext、ServletContext的关系

    转载:http://blog.csdn.net/c289054531/article/details/9196149?utm_source=tuicool&utm_medium=referra ...

  2. zoj Abs Problem

    Abs Problem Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Alice and Bob is pl ...

  3. Android Handler Message总结

    http://blog.csdn.net/caesardadi/article/details/8473777 当应用程序启动时,会开启一个主线程(也就是UI线程),由她来管理UI,监听用户点击,来响 ...

  4. EI表达式和JSTL

    JSP九大内置对象     WEB域内置对象(存值取值,传值数据用的)    setAttribute/getAttribute;    page  基本不用/ pageContext 只在本页面有效 ...

  5. Reading Csv Files with Text_io in Oracle D2k Forms

    Below is the example to read and import comma delimited csv file in oracle forms with D2k_Delimited_ ...

  6. 07.常用的SQL语句

    常用SQL语句,仿照着写(只改动字段和表名,库名) 查看数据库引擎                SHOW ENGINES;(默认InnoDB) 用数据库生成UUID            selec ...

  7. CSS定位小技巧

    CSS定位Static 默认定位Relative 相对定位:left 和topposition: relative;/*相对定位*/ left:40px;/*在原来的位置向右移动*/ top:100p ...

  8. ABAP基本数据类型、通用类型

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  9. C# 导出数据至 CSV

    有时候将Excel的数据另存到csv文件会出现csv格式错误,以下示例实现将DataTable里面的数据直接保存到csv文件. System.Web.HttpRuntime.Cache["v ...

  10. CALayer总结(一)

    1.geometryFlipped   设置为yes,则子图层或者子视图本来相对于左上角放置 改为 相对于左下角放置: 2.contents 3.contentGravity: kCAGravityC ...