使用ICMP协议Ping网络主机
#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网络主机的更多相关文章
- ICMP协议Ping命令的应用
ICMP的全称是 Internet Control Message Protocol ,它是TCP/IP协议族的一个子协议,属于网络层协议,用于在IP主机.路由器之间传递控制消息.从技术角度来讲,就是 ...
- 计网-ping服务命令与ICMP协议
目录 一.IP协议的助手 —— ICMP 协议(网络层协议) 二.ping —— 查询报文类型的使用 三.traceroute —— 差错报文类型的使用 参考:从Wireshark抓包软件角度理解PI ...
- IP协议的助手 —— ICMP 协议
IP协议的助手 —— ICMP 协议 IP协议的助手 —— ICMP 协议 ping 是基于 ICMP 协议工作的,所以要明白 ping 的工作,首先我们先来熟悉 ICMP 协议. ICMP 是什么? ...
- UNIX网络编程——利用ARP和ICMP协议解释ping命令
一.MTU 以太网和IEEE 802.3对数据帧的长度都有限制,其最大值分别是1500和1492字节,将这个限制称作最大传输单元(MTU,Maximum Transmission Unit) ...
- 网络协议 5 - ICMP 与 ping:投石问路的侦察兵
日常开发中,我们经常会碰到查询网络是否畅通以及域名对应 IP 地址等小需求,这时候用的最多的应该就是 ping 命令了. 那你知道 ping 命令是怎么工作的吗?今天,我们就来一起认识下 pi ...
- 【网络协议】ICMP协议、Ping、Traceroute
ICMP协议 ICMP常常被觉得是IP层的一个组成部分,它是网络层的一个协议.它传递差错报文以及其它须要注意的信息.ICMP报文通常被IP层或更高层(TCP.UDP等)使用,它是在IP数据报内 ...
- 网络协议 5 - ICMP 与 Ping
日常开发中,我们经常会碰到查询网络是否畅通以及域名对应 IP 地址等小需求,这时候用的最多的应该就是 ping 命令了. 那你知道 ping 命令是怎么工作的吗?今天,我们就来一起认识下 ping 命 ...
- Linux用ICMP协议实现简单Ping网络监测功能
ICMP是(Internet Control Message Protocol)Internet控制报文协议.它是TCP/IP协议族的一个子协议,用于在IP主机.路由器之间传递控制消息.控制消息是指网 ...
- 网络协议学习笔记(二)物理层到MAC层,交换机和VLAN,ICMP与ping原理
概述 之前网络学习笔记主要讲解了IP的诞生,或者说整个操作系统的诞生,一旦有了IP,就可以在网络的环境里和其他的机器展开沟通了.现在开始给大家讲解关于网络底层的相关知识. 从物理层到MAC层:如何在宿 ...
随机推荐
- 使用Markdown写文档
转载于:http://blog.csdn.net/xiahouzuoxin/article/details/19752603 Markdown是一种网络书写语言,其目标是实现易读易写,且兼容HTML语 ...
- JS实现base64编码与解码
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ...
- reactjs入门到实战(六)---- ReactJS组件API详解
全局的api 1.React.createClass 创建一个组件类,并作出定义.组件实现了 render() 方法,该方法返回一个子级.该子级可能包含很深的子级结构.组件与标准原型类的不同之处在于, ...
- qt中信号与槽机制
一. 简介 就我个人来理解,信号槽机制与Windows下消息机制类似,消息机制是基于回调函数,Qt中用信号与槽来代替函数指针,使程序更安全简洁. 信号和槽机制是 Qt 的核心机制,可以让编程人员将互不 ...
- java反编译工具JD-GUI
这款java反编译工具是由C++写的,是一款免费的非商业用途的软件,(Xjad也不错,但是不支持jar反编译) 一.支持众多.class反编译工具 二.支持反编译jar
- window server开发
代码部分: public partial class tv : ServiceBase { public tv() { InitializeComponent(); ServiceName = &qu ...
- 并行parallel和并发concurrent的区别
http://stackoverflow.com/questions/1050222/concurrency-vs-parallelism-what-is-the-difference Concurr ...
- Oracle的数据恢复——Flashback用法汇总
/* 11g的flashbackup 分好几种,分别用途不一样. A.flashback database 闪回数据库,简单理解就是把数据库闪回到某个以前的时间点, 能恢复到的最早的SCN, 取决与F ...
- Python基础学习笔记(四)语句
参考资料: 1. <Python基础教程> 2. http://www.runoob.com/python/python-chinese-encoding.html 3. http://w ...
- Zookeeper相关知识
一.Zookeeper是什么? Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务.状态同步服务. ...