Python找出9个连续的空闲端口


Posted in Python onFebruary 01, 2016

一、项目需求

安装某软件,配置时候需要填写空闲的端口。查看5个平台的某个端口是否被占用

5个平台为windows, linux, aix, hp, solaris

二、实现方案有两种

1、利用 python 的 socket 模块里的

def isInuse(ipList, port):
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  flag=True
  for ip in ipList:
    try:
      s.connect((ip, int(port)))
      s.shutdown(2)
      print '%d is inuse' % port
      flag=True
      break
    except:
      print '%d is free' % port
      flag=False
  return flag

在try 模块中 如果 s.connect((ip, int(port))) 如果能成功, 说明端口被占用.

否则, connect 不成功, 会进到except 中, 说明端口不被占用.

但是有个问题, 端口监听的ip 除了 "127.0.0.1","0.0.0.0" 还有可能是本机的局域网ip 如 222.25.136.17 , 或者与之通信的那台机器的ip。

可以通过这个方法获得局域网 ip

def getLocalIp():
  localIP = socket.gethostbyname(socket.gethostname())
  return localIP

本代码只针对 ipList = ("127.0.0.1","0.0.0.0",getLocalIp()) 这3个 ip 进行 connect

import sys
import os
import socket


def isInuse(ipList, port):
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  flag=True
  for ip in ipList:
    try:
      s.connect((ip, int(port)))
      s.shutdown(2)
      print '%d is inuse' % port
      flag=True
      break
    except:
      print '%d is free' % port
      flag=False
  return flag


def getLocalIp():
  localIP = socket.gethostbyname(socket.gethostname())
  return localIP

def checkNinePort(startPort):
  flag = True
  ipList = ("127.0.0.1","0.0.0.0",getLocalIp())
  for i in range(1, 10):
    if (isInuse(ipList, startPort)):
      flag = False
      break
    else:
      startPort = startPort + 1
  return flag, startPort


def findPort(startPort):
  while True:
    flag, endPort = checkNinePort(startPort)
    if (flag == True): #ninePort is ok
      break
    else:
      startPort = endPort + 1
  return startPort


def main():
  startPort=51988
  # startPort = int(sys.argv[1])
  print findPort(startPort)

main()

2. 利用netstat 输出信息查找端口号匹配

第一种方法的准确性依赖于 connect((ip, int(port))) 中的 ip,到底怎样的 ip 集合才是完备的, 可以确定这个端口不被占用?

于是, 有下面这个方法

**在 linux 用 netstat -tnpl 可以得到端口监听信息,

观察 tcp 0 0 10.173.1.208:3210 0.0.0.0:* LISTEN 55563/repserver

出现了 10.173.1.208:3210 所以 3210 端口是被占用的

对这些信息进行搜索 :5000, 如果存在, 就表示5000端口是LISTEN**.

如果输出结果中不存在 :5000 的相关字符,表示这个端口不被占用.

netstat - tnpl | grep 321

tcp 0 0 10.173.1.208:3211 0.0.0.0:* LISTEN 55563/***
tcp 0 0 0.0.0.0:3212 0.0.0.0:* LISTEN 55586/***
tcp 0 0 10.173.1.208:3213 0.0.0.0:* LISTEN 55707/***
tcp 0 0 0.0.0.0:3214 0.0.0.0:* LISTEN 54272/java
tcp 0 0 0.0.0.0:3215 0.0.0.0:* LISTEN 54272/java
tcp 0 0 10.173.1.208:3216 0.0.0.0:* LISTEN 54822/***
tcp 0 0 10.173.1.208:3217 0.0.0.0:* LISTEN 34959/***
tcp 0 0 10.173.1.208:3218 0.0.0.0:* LISTEN 54849/***

依据这个思路, 给出代码.

AIX 、HP 、WINDOWS、 LINUX、 SOLARIS 这几个平台查看端口信息的方式不同,

先进行机器平台的判断

然后调用各个平台的端口占用判断函数

如果要找出连续端口, 其中只要有一个端口占用, 就跳出循环

__author__ = 'I316736'
import os
import platform
import sys


def isInuseWindow(port):
  if os.popen('netstat -an | findstr :' + str(port)).readlines():
    portIsUse = True
    print '%d is inuse' % port
  else:
    portIsUse = False
    print '%d is free' % port
  return portIsUse

def isInuseLinux(port):
  #lsof -i:4906
  #not show pid to avoid complex
  if os.popen('netstat -na | grep :' + str(port)).readlines():
    portIsUse = True
    print '%d is inuse' % port
  else:
    portIsUse = False
    print '%d is free' % port
  return portIsUse

def isInuseAix(port):
  if os.popen('netstat -Aan | grep "\.' + str(port) + ' "').readlines():
    portIsUse = True
    print '%d is inuse' % port
  else:
    portIsUse = False
    print '%d is free' % port
  return portIsUse

def isInuseHp(port):
  if os.popen('netstat -an | grep "\.' + str(port) + ' "').readlines():
    portIsUse = True
    print '%d is inuse' % port
  else:
    portIsUse = False
    print '%d is free' % port
  return portIsUse

def isInuseSun(port):
  if os.popen('netstat -an | grep "\.' + str(port) + ' "').readlines():
    portIsUse = True
    print '%d is inuse' % port
  else:
    portIsUse = False
    print '%d is free' % port
  return portIsUse

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()
  if 'windows-' in machine:
    return isInuseWindow
  elif 'linux-' in machine:
    return isInuseLinux
  elif 'aix-' in machine:
    return isInuseAix
  elif 'hp-' in machine:
    return isInuseHp
  elif 'sunos-' in machine:
    return isInuseSun
  else:
    print 'Error, sorry, platform is unknown'
    exit(-1)

def checkNinePort(startPort):
  isInuseFun = choosePlatform()
  nineIsFree = True
  for i in range(1, 10):
    if (isInuseFun(startPort)):
      nineIsFree = False
      break
    else:
      startPort = startPort + 1
  return nineIsFree, startPort


def findPort(startPort):
  while True:
    flag, endPort = checkNinePort(startPort)
    if (flag == True): # ninePort is ok
      break
    else:
      startPort = endPort + 1
  return startPort


def main(startPort):
  firstPort=findPort(startPort)
  print 'First port of nine free ports is ', firstPort

if __name__ == '__main__' :
  if len(sys.argv) > 1:
    print len(sys.argv)
    startPort = int(sys.argv[1])
  else:
    startPort = 500
  main(startPort)

相关知识点总结

os.popen()
可以调用系统的一些shell命令

os.popen().readlines()
读取调用shell命令后的回显信息

netstat -tnpl 

-tnpl 各个参数的含义
-l或--listening  显示监控中的服务器的Socket。
-n或--numeric  直接使用IP地址,而不通过域名服务器。
-p或--programs  显示正在使用Socket的程序识别码和程序名称。
-t或--tcp  显示TCP传输协议的连线状况

----------

tcp 0 0 10.173.1.208:4903 0.0.0.0:* LISTEN 54849/jsagent
最后的54849/jsagent 表示 进程号 54849 进程名 jsagent

以上就是本文的全部内容,希望对大家的学习有所帮助。

Python 相关文章推荐
python读取html中指定元素生成excle文件示例
Apr 03 Python
Pycharm设置去除显示的波浪线方法
Oct 28 Python
Python API 自动化实战详解(纯代码)
Jun 11 Python
Python math库 ln(x)运算的实现及原理
Jul 17 Python
django框架使用方法详解
Jul 18 Python
Python计算两个矩形重合面积代码实例
Sep 16 Python
Python中__repr__和__str__区别详解
Nov 07 Python
Python打包工具PyInstaller的安装与pycharm配置支持PyInstaller详细方法
Feb 27 Python
基于打开pycharm有带图片md文件卡死问题的解决
Apr 24 Python
vscode调试django项目的方法
Aug 06 Python
python 密码学示例——凯撒密码的实现
Sep 21 Python
Pandas对每个分组应用apply函数的实现
Dec 13 Python
Python 爬虫的工具列表大全
Jan 31 #Python
python在不同层级目录import模块的方法
Jan 31 #Python
在Python中移动目录结构的方法
Jan 31 #Python
python嵌套函数使用外部函数变量的方法(Python2和Python3)
Jan 31 #Python
python 爬取微信文章
Jan 30 #Python
python生成验证码图片代码分享
Jan 28 #Python
详解Python网络爬虫功能的基本写法
Jan 28 #Python
You might like
删除无限分类并同时删除它下面的所有子分类的方法
2010/08/08 PHP
30个php操作redis常用方法代码例子
2014/07/05 PHP
thinkphp实现图片上传功能
2016/01/13 PHP
WordPress分页伪静态加html后缀
2016/06/08 PHP
PHP排序算法之希尔排序(Shell Sort)实例分析
2018/04/20 PHP
jQuery在vs2008及js文件中的无智能提示的解决方法
2010/12/30 Javascript
js防止表单重复提交实现代码
2012/09/05 Javascript
extjs3 combobox取value和text案例详解
2013/02/06 Javascript
用html5 js实现点击一个按钮达到浏览器全屏效果
2014/05/28 Javascript
使用jquery 简单实现下拉菜单
2015/01/14 Javascript
浅析Node.js中的内存泄漏问题
2015/06/23 Javascript
javascript获取本机操作系统类型的方法
2015/08/13 Javascript
jQuery实现的文字hover颜色渐变效果实例
2016/02/20 Javascript
文本框只能输入数字的js代码(含小数点)
2016/07/10 Javascript
JavaScript中join()、splice()、slice()和split()函数用法示例
2018/08/24 Javascript
vue-cli 脚手架基于Nightwatch的端到端测试环境的过程
2018/09/30 Javascript
在移动端使用vue-router和keep-alive的方法示例
2018/12/02 Javascript
微信分享invalid signature签名错误踩过的坑
2020/04/11 Javascript
使用Vue实现一个树组件的示例
2020/11/06 Javascript
vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示)
2020/11/12 Javascript
Python的Django框架中的URL配置与松耦合
2015/07/15 Python
Python AES加密模块用法分析
2017/05/22 Python
python正向最大匹配分词和逆向最大匹配分词的实例
2018/11/14 Python
Django在admin后台集成TinyMCE富文本编辑器的例子
2019/08/09 Python
浅谈图像处理中掩膜(mask)的意义
2020/02/19 Python
解决Keras中Embedding层masking与Concatenate层不可调和的问题
2020/06/18 Python
英国婴儿及儿童产品商店:TigerParrot
2019/03/04 全球购物
大专生工程监理求职信
2013/10/04 职场文书
事务机电主管工作职责
2014/02/25 职场文书
学校门卫岗位职责
2014/03/16 职场文书
四查四看整改措施
2014/09/19 职场文书
法人代表证明书格式
2014/10/01 职场文书
债务授权委托书范本
2014/10/17 职场文书
安全教育第一课观后感
2015/06/17 职场文书
2019企业给员工的慰问信
2019/06/24 职场文书
创业计划书之o2o水果店
2019/08/30 职场文书