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展示动态规则法用以解决重叠子问题的示例
Apr 02 Python
详细解读tornado协程(coroutine)原理
Jan 15 Python
Python在for循环中更改list值的方法【推荐】
Aug 17 Python
对pandas的层次索引与取值的新方法详解
Nov 06 Python
对python操作kafka写入json数据的简单demo分享
Dec 27 Python
Python函数返回不定数量的值方法
Jan 22 Python
对Python函数设计规范详解
Jul 19 Python
Python3并发写文件与Python对比
Nov 20 Python
python微信公众号开发简单流程实现
Mar 09 Python
Pytorch 使用opnecv读入图像由HWC转为BCHW格式方式
Jun 02 Python
使用Python FastAPI构建Web服务的实现
Jun 08 Python
tensorflow2.0教程之Keras快速入门
Feb 20 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
php数组函数序列之rsort() - 对数组的元素值进行降序排序
2011/11/02 PHP
递归删除一个节点以及该节点下的所有节点示例
2014/03/19 PHP
解决php的“It is not safe to rely on the system’s timezone settings”问题
2015/10/08 PHP
PHP命名空间和自动加载类
2016/04/03 PHP
jQuery setTimeout()函数使用方法
2013/04/07 Javascript
JS执行删除前的判断代码
2014/02/18 Javascript
js获取url中"?"后面的字串方法
2014/05/15 Javascript
jQuery横向擦除焦点图特效代码分享
2015/09/06 Javascript
AngularJS中的Promise详细介绍及实例代码
2016/12/13 Javascript
AngularJS使用ng-app自动加载bootstrap框架问题分析
2017/01/04 Javascript
详解angularjs获取元素以及angular.element()用法
2017/07/25 Javascript
ES6中Class类的静态方法实例小结
2017/10/28 Javascript
微信小程序分享功能之按钮button 边框隐藏和点击隐藏
2018/06/14 Javascript
vue模块拖拽实现示例代码
2019/03/09 Javascript
AjaxFileUpload.js实现异步上传文件功能
2019/04/19 Javascript
解决vue自定义全局消息框组件问题
2019/11/22 Javascript
node.js中Buffer缓冲器的原理与使用方法分析
2019/11/23 Javascript
Javascript中Math.max和Math.max.apply的区别和用法详解
2020/08/24 Javascript
js实现类选择器和name属性选择器的示例步骤
2021/02/07 Javascript
[00:32]DOTA2上海特级锦标赛 COL战队宣传片
2016/03/04 DOTA
浅谈python函数之作用域(python3.5)
2017/10/27 Python
Python实现插入排序和选择排序的方法
2019/05/12 Python
介绍一款python类型检查工具pyright(推荐)
2019/07/03 Python
自定义Django Form中choicefield下拉菜单选取数据库内容实例
2020/03/13 Python
详解HTML5中垂直上下居中的解决方案
2017/12/20 HTML / CSS
使用HTML5技术开发一个属于自己的超酷颜色选择器
2013/09/22 HTML / CSS
英国领先的运动物理治疗供应公司:Vivomed
2018/07/14 全球购物
即时搜索数百万张门票:SeatsForEveryone.com
2018/08/26 全球购物
大学生个人求职信范文
2013/09/21 职场文书
怎样有效的进行自我评价
2013/10/06 职场文书
升国旗仪式主持词
2014/03/19 职场文书
总经理人事任命书
2014/06/05 职场文书
国家税务局干部作风整顿整改措施
2014/09/18 职场文书
2014旅游局领导班子四风问题对照检查材料思想汇报
2014/09/19 职场文书
七年级英语教学反思
2016/02/15 职场文书
教你用python实现一个无界面的小型图书管理系统
2021/05/21 Python