首頁 >後端開發 >Python教學 >利用Python找出9個連續的空閒端口

利用Python找出9個連續的空閒端口

高洛峰
高洛峰原創
2017-03-13 18:06:451400瀏覽

這篇文章主要介紹了Python找出9個連續的空閒連接埠的方法,有興趣的小夥伴們可以參考一下

一、專案需求

安裝某軟體,設定時候需要填入空閒的連接埠。查看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找出9個連續的空閒端口的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn