Python批量检测服务器端口可用性与Socket函数使用

举报
技术火炬手 发表于 2019/08/27 10:20:33 2019/08/27
【摘要】 谁是最可怜的人今天中午睡觉感觉有点晃,还以为是地震了,吓了一跳。睡醒了鬼使神差的突然在想,如果地震房子塌了,还要不要还贷款啊?结果手机查了一下,瞬间就觉得要崩溃了,即便房子没了都还要继续还款…谁是最可怜的人,穷人。这几天公司有些忙,主要是涉及Python的Linux下脚本开发问题。其中涉及到针对服务器及端口的检测工作,所以今天和大家聊聊使用Python检测服务器与端口可用性的问题。socke...

谁是最可怜的人

今天中午睡觉感觉有点晃,还以为是地震了,吓了一跳。睡醒了鬼使神差的突然在想,如果地震房子塌了,还要不要还贷款啊?结果手机查了一下,瞬间就觉得要崩溃了,即便房子没了都还要继续还款…谁是最可怜的人,穷人。

image.png

这几天公司有些忙,主要是涉及Python的Linux下脚本开发问题。其中涉及到针对服务器及端口的检测工作,所以今天和大家聊聊使用Python检测服务器与端口可用性的问题。

socket函数

简述

socket又称套间字或者插口,是网络通信中必不可少的工具。有道是:“无socket,不网络”。由于socket最早在BSD Unix上使用,而Unix/Linux所奉为经典的至高哲学是“一切皆是文件”。因此socket在使用时也是完全符合这个哲学的,它涉及到listen()、bind()、accept()、write()/read()、close()等基本的类似于文件操作的功能函数。

socket用法

import socket
socket.socket(socket_family,socket_type,protocal=0)
#socket_family 可以是 AF_UNIX 或 AF_INET。socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。protocol 一般不填,默认值为 0。

#获取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#获取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

#由于 socket 模块中有太多的属性。我们在这里破例使用了'from module import *'语句。

#使用 'from socket import *',我们就把 socket 模块里的所有属性都带到我们的命名空间里了,这样能 大幅减短我们的代码。

#例如tcpSock = socket(AF_INET, SOCK_STREAM)

服务端套接字

s.bind() #绑定(主机,端口号)到套接字

s.listen() #开始TCP监听

s.accept() #被动接受TCP客户的连接,(阻塞式)等待连接的到来

客户端套接字

s.connect() #主动初始化TCP服务器连接

s.connect_ex() #connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

公共用途套接字

s.recv() #接收TCP数据

s.send() #发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)

s.sendall() #发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)

s.recvfrom() #接收UDP数据

s.sendto() #发送UDP数据

s.getpeername() #连接到当前套接字的远端的地址

s.getsockname() #当前套接字的地址

s.getsockopt() #返回指定套接字的参数

s.setsockopt() #设置指定套接字的参数

s.close() #关闭套接字

面向锁的套接字

s.setblocking() #设置套接字的阻塞与非阻塞模式

s.settimeout() #设置阻塞套接字操作的超时时间

Python检测端口

上面介绍了socket的一些基础信息,那么需求是什么?批量检测服务器、端口,是否被占用…

听起来比较简单,起初也是这么认为的。但socket的坑确实不少啊!

连接方式

上面提到了s.connect()与s.connect_ex(),更推荐使用s.connect_ex(),而非使用主动连接的s.connect()获取异常方式。

这样我们可以通过异常码更方便的进行判断操作。基础操作:

# -*- coding: utf-8 -*-
# @Author   : 王翔
# @JianShu  : 清风Python
# @Date     : 2019/8/27 1:26
# @Software : PyCharm
# @version  :Python 3.7.3
# @File     : IpPortCheck.py

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex(('127.0.0.1', 80))
print(result)

快速检测

当我们了解了基础操作后,可以进行下一步的检测工作,但此时我们忽略了一个问题,刚才我们检测的是本机的ip,但如果我们检测的是一个不存在的ip时会出现什么问题?

如果我们使用connect方法触发异常,并返回:

image.png

如果我们使用connect_ex,则打印返回码10060。

但两者都存在一个问题,就是超时时间会等待很久。那么如何操作?一般的网络监测,设置3秒的时间就够了,所以添加s.settimeout(3)配置即可,当超时后,会引发socket.timeout: timed out异常,使用connect_ex则返回10035的状态码。

关于异常报错

TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。

ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝,无法连接。

完整判断代码

# -*- coding: utf-8 -*-
# @Author   : 王翔
# @JianShu  : 清风Python
# @Date     : 2019/8/27 1:26
# @Software : PyCharm
# @version  :Python 3.7.3
# @File     : IpPortCheck.py

import socket

IPs = ['127.0.0.1', '10.45.226.74']
Ports = [22, 80, 8080]

for ip in IPs:
   for port in Ports:
       s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
       s.settimeout(3)
       result = s.connect_ex((ip, port))
       if result == 0:
           print("The Server IP: {} , Port {} has been used".format(ip, port))
       elif result == 10061:
           print("The Server IP: {} , Port {} not enabled".format(ip, port))
       elif result == 10035:
           print("The Server IP: {} , no response".format(ip, port))
       else:
           print(result)
       s.close()

output:
The Server IP: 127.0.0.1 , Port 22 not enabled
The Server IP: 127.0.0.1 , Port 80 has been used
The Server IP: 127.0.0.1 , Port 8080 not enabled
The Server IP: 10.45.226.74 , no response
The Server IP: 10.45.226.74 , no response
The Server IP: 10.45.226.74 , no response

The End

本文来自“清风Python”公众号



【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。