小言_互联网的博客

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

365人阅读  评论(0)

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方法触发异常,并返回:

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

如果我们使用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

OK,今天的内容就到这里,如果觉得内容对你有所帮助,欢迎点击文章右下角的“在看”。
期待你关注我的公众号清风Python,如果觉得不错,希望能动动手指转发给你身边的朋友们。

作者:清风Python


转载:https://blog.csdn.net/devcloud/article/details/100098991
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场