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实现雨滴下落到地面效果
Jun 21 Python
Python实现爬虫抓取与读写、追加到excel文件操作示例
Jun 27 Python
Python基于百度云文字识别API
Dec 13 Python
深入解析python中的实例方法、类方法和静态方法
Mar 11 Python
Python Opencv实现图像轮廓识别功能
Mar 23 Python
Python实现九宫格式的朋友圈功能内附“马云”朋友圈
May 07 Python
Python配置虚拟环境图文步骤
May 20 Python
Python-copy()与deepcopy()区别详解
Jul 12 Python
python打印直角三角形与等腰三角形实例代码
Oct 20 Python
Python图像处理库PIL中图像格式转换的实现
Feb 26 Python
解决Python paramiko 模块远程执行ssh 命令 nohup 不生效的问题
Jul 14 Python
Python实现一个论文下载器的过程
Jan 18 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
学习discuz php 引入文件的方法DISCUZ_ROOT
2009/06/21 PHP
php empty() 检查一个变量是否为空
2011/11/10 PHP
如何用php获取文件名后缀
2013/06/09 PHP
jQuery+php实现ajax文件即时上传的详解
2013/06/17 PHP
php-redis中的sort排序函数总结
2015/07/08 PHP
smarty自定义函数用法示例
2016/05/20 PHP
PHP7创建COOKIE和销毁COOKIE的实例方法
2020/02/03 PHP
用js实现的一个Flash滚动轮换显示图片代码生成器
2007/03/14 Javascript
js修改input的type属性及浏览器兼容问题探讨与解决
2013/01/23 Javascript
IE8的JavaScript点击事件(onclick)不兼容的解决方法
2013/11/22 Javascript
js基于面向对象实现网页TAB选项卡菜单效果代码
2015/09/09 Javascript
jQuery如何获取动态添加的元素
2016/06/24 Javascript
a标签跳转到指定div,jquery添加和移除class属性的实现方法
2016/10/10 Javascript
canvas学习之API整理笔记(一)
2016/12/29 Javascript
Javascript设计模式之装饰者模式详解篇
2017/01/17 Javascript
详解微信小程序 登录获取unionid
2017/06/27 Javascript
在vue中添加Echarts图表的基本使用教程
2017/11/22 Javascript
React组件中的this的具体使用
2018/02/28 Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
2019/04/03 Javascript
微信小程序webview 脚手架使用详解
2019/07/22 Javascript
聊聊鉴权那些事(推荐)
2019/08/22 Javascript
JavaScript实现拖动对话框效果的实现代码
2020/10/12 Javascript
[34:47]完美世界DOTA2联赛PWL S2 Magma vs LBZS 第一场 11.18
2020/11/18 DOTA
Python中的下划线详解
2015/06/24 Python
详解TensorFlow在windows上安装与简单示例
2018/03/05 Python
解决pycharm debug时界面下方不出现step等按钮及变量值的问题
2020/06/09 Python
HttpServlet类中的主要方法都有哪些?各自的作用是什么?
2014/03/16 面试题
幼师求职自荐信范文
2014/01/26 职场文书
电气个人求职信范文
2014/02/04 职场文书
小学秋季运动会报道稿
2014/09/30 职场文书
个人租房协议书样本
2014/10/01 职场文书
干部作风整顿个人剖析材料
2014/10/06 职场文书
离婚协议书范本
2015/01/26 职场文书
2016年小学教师师德承诺书
2016/03/25 职场文书
少年的你:世界上没有如果,要在第一次就勇敢的反抗
2019/11/20 职场文书
MySQL之高可用集群部署及故障切换实现
2021/04/22 MySQL