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 socket 超时设置 errno 10054
Jul 01 Python
python的即时标记项目练习笔记
Sep 18 Python
python获取当前计算机cpu数量的方法
Apr 18 Python
浅谈插入排序算法在Python程序中的实现及简单改进
May 04 Python
python使用RNN实现文本分类
May 24 Python
详解Django 时间与时区设置问题
Jul 23 Python
python正则表达式匹配不包含某几个字符的字符串方法
Jul 23 Python
python实现俄罗斯方块小游戏
Apr 24 Python
PyCharm2020.1.2社区版安装,配置及使用教程详解(Windows)
Aug 07 Python
利用python 读写csv文件
Sep 10 Python
详细总结Python常见的安全问题
May 21 Python
使用scrapy实现增量式爬取方式
Jun 21 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
动漫定律:眯眯眼都是怪物!这些角色狠话不多~
2020/03/03 日漫
PHP实现自动识别Restful API的返回内容类型
2015/02/07 PHP
PHP cURL初始化和执行方法入门级代码
2015/05/28 PHP
joomla实现注册用户添加新字段的方法
2016/05/05 PHP
PHPExcel在linux环境下导出报500错误的解决方法
2017/01/26 PHP
php中通过eval实现字符串格式的计算公式
2017/03/18 PHP
php求斐波那契数的两种实现方式【递归与递推】
2019/09/09 PHP
javascript 事件绑定问题
2011/01/01 Javascript
html页面显示年月日时分秒和星期几的两种方式
2013/08/20 Javascript
jquery 设置元素相对于另一个元素的top值(实例代码)
2013/11/06 Javascript
jQuery focus和blur事件的应用详解
2014/01/26 Javascript
基于javascript实现精确到毫秒的倒计时限时抢购
2016/04/17 Javascript
JS Attribute属性操作详解
2016/05/19 Javascript
javascript基础语法——全面理解变量和标识符
2016/06/02 Javascript
javascript实现复选框全选或反选
2017/02/04 Javascript
canvas实现图像截取功能
2017/02/06 Javascript
JavaScript+Html5实现按钮复制文字到剪切板功能(手机网页兼容)
2017/03/30 Javascript
微信小程序 图片绝对定位(背景图片)
2017/04/05 Javascript
js canvas实现放大镜查看图片功能
2017/06/08 Javascript
jQuery实现倒计时功能 jQuery实现计时器功能
2017/09/19 jQuery
jQuery选择器之子元素过滤选择器
2017/09/28 jQuery
Vue中的v-for循环key属性注意事项小结
2018/08/12 Javascript
对vue中的事件穿透与禁止穿透实例详解
2019/10/28 Javascript
在Webpack中用url-loader处理图片和字体的问题
2020/04/28 Javascript
JavaScript 类的封装操作示例详解
2020/05/16 Javascript
[07:52]2014DOTA2 TI逗比武士游V社解说背后的故事
2014/07/10 DOTA
用Python实现读写锁的示例代码
2018/11/05 Python
python之yield和Generator深入解析
2019/09/18 Python
连卡佛中国官网:Lane Crawford中文站
2018/01/27 全球购物
ShellScript面试题一则-ShellScript编程
2014/06/24 面试题
财务主管的岗位职责
2013/12/30 职场文书
宾馆总经理岗位职责
2014/02/14 职场文书
个人自我鉴定总结
2014/03/25 职场文书
蓝颜请假条
2014/04/11 职场文书
社区班子个人对照检查材料思想汇报
2014/10/07 职场文书
MIME类型中application/xml与text/xml的区别介绍
2022/01/18 HTML / CSS