2013-10-05 3 views

ответ

80

Вы можете использовать socket module, чтобы просто проверить, открыт ли порт.

Это будет выглядеть примерно так.

import socket 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
result = sock.connect_ex(('127.0.0.1',80)) 
if result == 0: 
    print "Port is open" 
else: 
    print "Port is not open" 
+7

Это имеет очевидные недостатки, которые должны быть отмечены: просто попытаться проверить соединение может 1) не из-за брандмауэр или временный перелив, 2) вызвать нежелательную реакцию соединить попытку в случае какой-либо активной защиты, 3) просто журналы и статистика использования ... Проверка использования специально выделенных инструментов как netstat обычно является предпочтительной. – Netch

+1

@Netch - это действительно удобно, когда вы находитесь на коробке, в которую вы не хотите устанавливать дополнительные инструменты, и вам нужно проверить, открыт ли удаленный порт. , , –

+0

@WyattBarnett netstat не является дополнительным инструментом (по крайней мере, на * nix) :) – Pitto

1

Netstat инструмент просто разбирает некоторые/Proc файлы, такие как/Proc/нетто/TCP и объединяет его с содержимым других файлов. Да, это очень специфично для платформы, но для Linux-единственного решения вы можете придерживаться этого. Документация ядра Linux подробно описывает эти файлы, чтобы вы могли найти их, как их читать.

Также обратите внимание, что ваш вопрос слишком неоднозначен, поскольку «порт» также может означать последовательный порт (/ dev/ttyS * и аналоги), параллельный порт и т. Д .; Я снова использовал понимание из другого ответа, это сетевой порт, но я бы попросил вас сформулировать ваши вопросы более точно.

13

Если вы заботитесь только о локальной машине, вы можете положиться на пакет psutil. Вы можете:

  1. Проверьте все порты, используемые конкретный PID:

    proc = psutil.Process(pid) 
    print proc.connections() 
    
  2. Проверьте все порты, используемые на локальной машине:

    print psutil.net_connections() 
    

Он работает на Windows тоже.

http://pythonhosted.org/psutil/

+2

Я обычно избегаю решений non-stdlib, но gdi, psutil должен просто быть в stdlib, его слишком важно. – ThorSummoner

+0

Часть 2 - это именно то, что я искал, но psutil не имеет функции net_connections(). Это не доступно в Python 2? Я в ubuntu. – qwerty9967

+0

@ qwerty9967 Не знаю, я думаю, вы должны проверить, можете ли вы обновить (оба python, если у вас есть pre-2.7 или пакет psutil, предпочтительно используя 'pip', а не apt-get/yum) – Joe

1

Просто добавляли к раствору mrjandro быстрый хак, чтобы избавиться от простых соединений ошибок/тайм-ауты.

Вы можете изменить пороговое значение переменной max_error_count и добавить уведомления любого типа.

import socket 

max_error_count = 10 

def increase_error_count(): 
    # Quick hack to handle false Port not open errors 
    with open('ErrorCount.log') as f: 
     for line in f: 
      error_count = line 
    error_count = int(error_count) 
    print "Error counter: " + str(error_count) 
    file = open('ErrorCount.log', 'w') 
    file.write(str(error_count + 1)) 
    file.close() 
    if error_count == max_error_count: 
     # Send email, pushover, slack or do any other fancy stuff 
     print "Sending out notification" 
     # Reset error counter so it won't flood you with notifications 
     file = open('ErrorCount.log', 'w') 
     file.write('0') 
     file.close() 

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.settimeout(2) 
result = sock.connect_ex(('127.0.0.1',80)) 
if result == 0: 
     print "Port is open" 
else: 
     print "Port is not open" 
     increase_error_count() 

И здесь вы найдете совместимую версию Python 3 (только фиксированный синтаксис печати):

import socket 

max_error_count = 10 

def increase_error_count(): 
    # Quick hack to handle false Port not open errors 
    with open('ErrorCount.log') as f: 
     for line in f: 
      error_count = line 
    error_count = int(error_count) 
    print ("Error counter: " + str(error_count)) 
    file = open('ErrorCount.log', 'w') 
    file.write(str(error_count + 1)) 
    file.close() 
    if error_count == max_error_count: 
     # Send email, pushover, slack or do any other fancy stuff 
     print ("Sending out notification") 
     # Reset error counter so it won't flood you with notifications 
     file = open('ErrorCount.log', 'w') 
     file.write('0') 
     file.close() 

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.settimeout(2) 
result = sock.connect_ex(('127.0.0.1',80)) 
if result == 0: 
     print ("Port is open") 
else: 
     print ("Port is not open") 
     increase_error_count() 
+0

//, NIIIIIICE. Это работает на Python 3? –

+0

Привет! Вам понадобятся некоторые незначительные изменения в функциях печати там ... Проверить новую версию, которую я вставил :) Вы можете легко изменить ее, чтобы не сохранять данные в файл журнала, например. – Pitto

18

Если вы хотите использовать это в более общем контексте, вы должны убедиться, что розетка что вы открываете и закрывается. Поэтому проверка должна быть более такой:

import socket 
from contextlib import closing 

def check_socket(host, port): 
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock: 
     if sock.connect_ex((host, port)) == 0: 
      print "Port is open" 
     else: 
      print "Port is not open" 
8

Для меня приведенные выше примеры зависали, если бы порт не был открыт. Строка 4 показывает использование SetTimeout для предотвращения подвешивания

import socket 

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.settimeout(2)          #2 Second Timeout 
result = sock.connect_ex(('127.0.0.1',80)) 
if result == 0: 
    print 'port OPEN' 
else: 
    print 'port CLOSED, connect_ex returned: '+str(result) 
+0

голосуйте за таймаут – Ivelin

0

В случае, когда вы зондирование TCP портов с целью слушать на нем, то лучше на самом деле назвать слушать.Подход с tring для подключения не «видит» клиентские порты установленных соединений, потому что никто не слушает его. Но эти порты не могут быть использованы для прослушивания.

import socket 


def check_port(port, rais=True): 
    """ True -- it's possible to listen on this port for TCP/IPv4 or TCP/IPv6 
    connections. False -- otherwise. 
    """ 
    try: 
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     sock.bind(('127.0.0.1', port)) 
     sock.listen(5) 
     sock.close() 
     sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) 
     sock.bind(('::1', port)) 
     sock.listen(5) 
     sock.close() 
    except socket.error as e: 
     return False 
     if rais: 
      raise RuntimeError(
       "The server is already running on port {0}".format(port)) 
    return True 
Смежные вопросы