Тестирование подключения к сокету в Python

Этот вопрос будет расширен на: Лучший способ открыть сокет в Python
При открытии сокета, как я могу проверить, установлен ли он, не истек ли тайм-аут или вообще не прошел ли он.

Редактировать: Я пробовал это:

try:
    s.connect((address, '80'))
except:
    alert('failed' + address, 'down')

но функция предупреждения вызывается даже тогда, когда это соединение должно было работать.

Вы всегда должны использовать print_exc () из модуля трассировки в разделе except! что укажет на случайные ошибки.

Alex 29.07.2012 13:54
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
26
1
106 056
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Кажется, вы поймаете не то исключение, которое хотите там поймать :)

если s является объектом socket.socket(), то правильным способом вызова .connect будет:

import socket
s = socket.socket()
address = '127.0.0.1'
port = 80  # port number is a number, not string
try:
    s.connect((address, port)) 
    # originally, it was 
    # except Exception, e: 
    # but this syntax is not supported anymore. 
except Exception as e: 
    print("something's wrong with %s:%d. Exception is %s" % (address, port, e))
finally:
    s.close()

Всегда пытайтесь увидеть, что это за исключение, которое вы улавливаете в цикле try-except.

Вы можете проверить, какие типы исключений в модуле сокета представляют, какие ошибки (тайм-аут, невозможность разрешения адреса и т. д.), И сделать отдельный оператор except для каждой из них - таким образом вы сможете по-разному реагировать на разные типы проблем.

Кажется, это не работает, даже если функция предупреждения не вызывается.

UnkwnTech 07.10.2008 11:10

попробуйте переместить s.connect из блока try :. какую ошибку вы получите?

kender 07.10.2008 11:18

не забудьте закрыть сокет после тестирования, когда он открыт. :)

marathon 06.02.2014 01:04

//, @kender, почему вы выбрали букву s в качестве имени переменной для объекта socket.socket()? Это неформальная конвенция?

Nathan Basanese 12.01.2016 00:03

// Также, как вы думаете, будет ли этот пример Python работать в Python 3.5?

Nathan Basanese 12.01.2016 00:05

@NathanBasanese Я использовал s, так как OP имел это имя переменной в вопросе :)

kender 13.01.2016 14:42

@NathanBasanese для python3.5 - часть сокета работает. Часть except Exception, e: больше не поддерживается, вместо нее должен быть except Exception as e:. Отредактировал сообщение, чтобы включить это.

kender 13.01.2016 14:52

Вам действительно стоит опубликовать:

  1. Полный исходный код вашего примера
  2. Результат действительный, а не резюме

Вот мой код, который работает:

import socket, sys

def alert(msg):
    print >>sys.stderr, msg
    sys.exit(1)

(family, socktype, proto, garbage, address) = \
         socket.getaddrinfo("::1", "http")[0] # Use only the first tuple
s = socket.socket(family, socktype, proto)

try:
    s.connect(address) 
except Exception, e:
    alert("Something's wrong with %s. Exception type is %s" % (address, e))

Когда сервер слушает, я ничего не получаю (это нормально), когда он нет, я получаю ожидаемое сообщение:

Something's wrong with ('::1', 80, 0, 0). Exception type is (111, 'Connection refused')

//, как работает этот бит с назначением (family, socktype, proto, garbage, address) = \ ? Кстати, твердый ответ.

Nathan Basanese 12.01.2016 00:11

Имя хоста может иметь несколько IP-адресов - нужно перебирать все результаты getaddrinfo. Но он должен вызываться с идентификатором протокола, чтобы пропустить UDP и подобные записи: socket.getaddrinfo(address, port, 0, 0, socket.IPPROTO_TCP).

Mikhail T. 03.12.2018 20:51

Вы можете использовать функцию connect_ex. Это не вызывает исключения. Вместо этого возвращает целочисленное значение в стиле C (в C обозначается как errno):

s =  socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex((host, port))
s.close()
if result:
    print "problem with socket!"
else:
    print "everything it's ok!"

В случае result > 0 вы получите значение ошибки errno. Затем вы можете сделать что-то вроде print errno.errorcode[result], чтобы получить более полезную подсказку об ошибке.

Jens 05.11.2014 21:21

Независимо от того, установлено соединение или нет: connect_ex () всегда возвращает "0". У меня не работает

Coliban 06.02.2020 13:41

12 лет спустя для всех, у кого есть подобные проблемы.

try:
    s.connect((address, '80'))
except:
    alert('failed' + address, 'down')

не работает, потому что порт «80» является строкой. Ваш порт должен быть int.

try:
    s.connect((address, 80))

Это должно сработать. Не уверен, почему даже лучший ответ не увидел этого.

Другие вопросы по теме