zoukankan      html  css  js  c++  java
  • Python批量检测服务器端口可用性与Socket函数使用

    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

  • 相关阅读:
    kmp 算法
    jdk 和 cglib 的动态代理
    RestTemplate工具类
    bat脚本切换多个工程的分支
    字符串的左旋转
    输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8。
    枚举类型在JPA中的使用
    拾遗
    YAML DEMO
    kiali 1.26 anonymous策略修改为token
  • 原文地址:https://www.cnblogs.com/2020-zhy-jzoj/p/13165533.html
Copyright © 2011-2022 走看看