Python构造ICMP协议实现网络ping方法
前段时间在python中使用subprocess库调用命令行的ping命令来完成网络连通性测试,下面是笔者以前的文章,可以参考。
3、Python Tkinter 实现简单的ping GUI 。
上面的三篇文章都有ping功能的使用 ,但是笔者发现一个问题。python调用外部的命令来完成ping功能就不够Pythonic,既然python拥有众多库,而且有脚本属性,那么调用外部的命令就不能体现python的优势。第二就是,调用外部ping命令实在是太慢了,在交互式界面可以忍受,但是在脚本程序中就显得不够效率,特别是局域网中存在大量的服务器时 。
于是带着疑问,笔者github上搜索一番发现有两个方法,第一个还是命令行工具fping,可以批量完成ping,在此不做详细解读,但是笔者测试确实快,局域网24位掩码花了12秒,而且只有四台在线,不在线花的时间比在线ping的时间长。第二个是纯python的方式构造ICMP协议实现网络ping方法,发现了一本书“Python-Network-Programming-Cookbook” ,里面有很多关于网络编程的example,然后笔者找到了ping_remote_host.py脚本,研读一番,觉得有点意思。
此文章关注第二个纯python的方式构造ICMP协议实现网络ping方法,分享测试如下。代码托管在Python-Network-Programming-Cookbook-Second-Edition/3_2_ping_remote_host.py at master · PacktPublishing/Python-Network-Programming-Cookbook-Second-Edition (github.com) 。
要发送ping包需要要构造出icmp的完整包,下面是几个关键的函数。
函数do_checksum(),计算校验和;
函数receive_pong(),循环监听直到接收到数据报;
函数send_ping(),构造数据报,添加校验和后发送;
函数ping_once(),调用函数send_ping()和receive_pong()来完成一次ping ;
函数ping(),循环四次调用函数ping_once(),完成四次ping测试。
在CENTOS8中,使用time来计算,Python构造ping方法比iputils的ping命令是在快太多了。都是ping四次,Python ping 只有0.193秒,而iputils的ping需要3.039秒。
wireshark抓包TCMP协议,234长度(函数send_ping可以修改data长度)的是python的ping方法,74长度是的命令行的ping方法。python ping方法比ping命令方法的应答时间要快。