Python获取本机ip以及n个连续的可用端口号

背景:最近在使用Pywebio编写测试工具。Start server时,想快速知道本机可用的端口,且最好是连续的。

import os
import platform
import socket


# 获取本机ip地址
def extract_ip():
    st = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        st.connect(('10.255.255.255', 1))
        ip = st.getsockname()[0]
    except Exception:
        ip = '127.0.0.1'
    finally:
        st.close()
    return ip


# OS是windows
def is_inuse_windows(port):
    # os.popen()函数与cmd命令窗口之间建立一个双向通道,可以从cmd窗口和程序间相互读取信息
    if os.popen('netstat -an | findstr :' + str(port)).readlines():
        port_inuse = True
        print('{} is in use'.format(port))
    else:
        port_inuse = False
        print('{} is free'.format(port))
    return port_inuse


# OS是linux
def is_inuse_linux(port):
    # lsof -i:4906
    # not show pid to avoid complex
    if os.popen('netstat -na | grep :' + str(port)).readlines():
        port_inuse = True
        print('{} is in use'.format(port))
    else:
        port_inuse = False
        print('{} is free'.format(port))

    return port_inuse


# oS是aix
def is_inuse_aix(port):
    if os.popen('netstat -Aan | grep "\.' + str(port) + ' "').readlines():
        port_inuse = True
        print('{} is in use'.format(port))
    else:
        port_inuse = False
        print('{} is free'.format(port))
    return port_inuse


# OS是hp
def is_inuse_hp(port):
    if os.popen('netstat -an | grep "\.' + str(port) + ' "').readlines():
        port_inuse = True
        print('{} is in use'.format(port))
    else:
        port_inuse = False
        print('{} is free'.format(port))
    return port_inuse


# OS是sun
def is_inuse_sun(port):
    if os.popen('netstat -an | grep "\.' + str(port) + ' "').readlines():
        port_inuse = True
        print('{} is in use'.format(port))
    else:
        port_inuse = False
        print('{} is free'.format(port))
    return port_inuse


# 从startport开始找n个连续可用的端口
def find_available_nPorts(startPort, n):
    # 死循环一直查找,直到找到为止。
    while True:
        flag, endPort = checkPorts(startPort, n)
        # 直到n个连续ports都可用,才跳出循环。否则一直往后查找。
        if (flag == True):  # ninePort is ok
            break
        else:
            startPort = endPort + 1

    print(f'First port of {n} free ports is {startPort}')
    ports = list(range(startPort, startPort + n))
    print(f'{n} available ports: {ports}')
    return ports


# 从startport开始找n个连续可用的端口
def checkPorts(startPort, n):
    # 返回的是function:不同OS上检查端口是否占用的函数
    isInuseFunc = choosePlatform()
    nPortsIsFree = True
    for i in range(1, n + 1):
        # 如果端口被占用,跳出循环,如果端口未被占用,开始端口往后延一位
        if (isInuseFunc(startPort)):
            nPortsIsFree = False
            break
        else:
            startPort = startPort + 1
    return nPortsIsFree, startPort


# 获取本机操作系统,使用对应的命令查看端口号是否被占用
def choosePlatform():
    # 'Windows-7-6.1.7601-SP1'
    # 'AIX-1-00F739CE4C00-powerpc-32bit'
    # 'HP-UX-B.11.31-ia64-32bit'
    # 'Linux-3.0.101-0.35-default-x86_64-with-SuSE-11-x86_64'
    # 'SunOS-5.10-sun4u-sparc-32bit-ELF'

    # 获取本机的系统
    machine = platform.platform().lower()
    print(f"本机系统是:{machine} ")
    if 'windows-' in machine:
        return is_inuse_windows
    elif 'linux-' in machine:
        return is_inuse_linux
    elif 'aix-' in machine:
        return is_inuse_aix
    elif 'hp-' in machine:
        return is_inuse_hp
    elif 'sunos-' in machine:
        return is_inuse_sun
    else:
        print('Error, sorry, platform is unknown')
        exit(-1)


if __name__ == '__main__':
    print("本机ip地址: ", extract_ip())
    ports = find_available_nPorts(18887, 10)

运行结果:

本机ip地址:  172.x.x.x
本机系统是:windows-10-10.0.19045-sp0 
18887 is free
18888 is in use
本机系统是:windows-10-10.0.19045-sp0 
18889 is free
18890 is free
18891 is free
18892 is free
18893 is free
18894 is free
18895 is free
18896 is free
18897 is free
18898 is free
First port of 10 free ports is 18889
10 available ports: [18889, 18890, 18891, 18892, 18893, 18894, 18895, 18896, 18897, 18898]

Process finished with exit code 0

参考博文:
https://blog.csdn.net/sxf1061700625/article/details/123526907
https://www.jb51.net/article/79000.htm
http://www.gimoo.net/t/1904/5ca56e0a74bb4.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值