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中input()与raw_input()的区别分析
Feb 27 Python
python设计模式大全
Jun 27 Python
Python简单实现socket信息发送与监听功能示例
Jan 03 Python
numpy.random.seed()的使用实例解析
Feb 03 Python
对python遍历文件夹中的所有jpg文件的实例详解
Dec 08 Python
Python基于scipy实现信号滤波功能
May 08 Python
Python通过TensorFLow进行线性模型训练原理与实现方法详解
Jan 15 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
Jun 11 Python
python使用bs4爬取boss直聘静态页面
Oct 10 Python
Django如何使用asyncio协程和ThreadPoolExecutor多线程
Oct 12 Python
Numpy中np.max的用法及np.maximum区别
Nov 27 Python
Python页面加载的等待方式总结
Feb 28 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 验证码不显示只有一个小红叉的解决方法
2013/09/30 PHP
laravel框架使用FormRequest进行表单验证,验证异常返回JSON操作示例
2020/02/18 PHP
jQuery如何取id有.的值一般的方法是取不到的
2014/04/18 Javascript
jquery+css3打造一款ajax分页插件(自写)
2014/06/18 Javascript
推荐6款基于jQuery实现图片效果插件
2014/12/07 Javascript
JS实现判断碰撞的方法
2015/02/11 Javascript
解决jquery插件:TypeError:$.browser is undefined报错的方法
2015/11/21 Javascript
js操作数组函数实例小结
2015/12/10 Javascript
js中用cssText设置css样式的简单方法
2016/09/19 Javascript
TableSort.js表格排序插件使用方法详解
2017/02/10 Javascript
jQuery简单判断值是否存在于数组中的方法示例
2018/04/17 jQuery
Vue中的混入的使用(vue mixins)
2018/06/01 Javascript
Vue中的v-for指令不起效果的解决方法
2018/09/27 Javascript
轻量级富文本编辑器wangEditor结合vue使用方法示例
2018/10/10 Javascript
原生js实现碰撞检测
2020/03/12 Javascript
JavaScript find()方法及返回数据实例
2020/04/30 Javascript
Node.js API详解之 dns模块用法实例分析
2020/05/15 Javascript
原生js canvas实现鼠标跟随效果
2020/08/02 Javascript
JS异步宏队列微队列原理详解
2020/09/09 Javascript
python实现在每个独立进程中运行一个函数的方法
2015/04/23 Python
利用Anaconda完美解决Python 2与python 3的共存问题
2017/05/25 Python
Python简单处理坐标排序问题示例
2019/07/11 Python
python读取.mat文件的数据及实例代码
2019/07/12 Python
Python Django 简单分页的实现代码解析
2019/08/21 Python
Django框架反向解析操作详解
2019/11/28 Python
django框架单表操作之增删改实例分析
2019/12/16 Python
TensorFlow2.0:张量的合并与分割实例
2020/01/19 Python
tensorflow之并行读入数据详解
2020/02/05 Python
python 图像增强算法实现详解
2021/01/24 Python
公司前台辞职报告
2014/01/19 职场文书
五年级数学教学反思
2014/02/11 职场文书
优质服务演讲稿
2014/05/14 职场文书
校园广播站开场白
2015/06/01 职场文书
解析laravel使用workerman用户交互、服务器交互
2021/04/28 PHP
jdbc中自带MySQL 连接池实践示例
2022/07/23 MySQL
Mybatis 一级缓存和二级缓存原理区别
2022/09/23 Java/Android