Этот вопрос будет расширен на: Лучший способ открыть сокет в Python
При открытии сокета, как я могу проверить, установлен ли он, не истек ли тайм-аут или вообще не прошел ли он.
Редактировать:
Я пробовал это:
try:
s.connect((address, '80'))
except:
alert('failed' + address, 'down')
но функция предупреждения вызывается даже тогда, когда это соединение должно было работать.






Кажется, вы поймаете не то исключение, которое хотите там поймать :)
если 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 для каждой из них - таким образом вы сможете по-разному реагировать на разные типы проблем.
Кажется, это не работает, даже если функция предупреждения не вызывается.
попробуйте переместить s.connect из блока try :. какую ошибку вы получите?
не забудьте закрыть сокет после тестирования, когда он открыт. :)
//, @kender, почему вы выбрали букву s в качестве имени переменной для объекта socket.socket()? Это неформальная конвенция?
// Также, как вы думаете, будет ли этот пример Python работать в Python 3.5?
@NathanBasanese Я использовал s, так как OP имел это имя переменной в вопросе :)
@NathanBasanese для python3.5 - часть сокета работает. Часть except Exception, e: больше не поддерживается, вместо нее должен быть except Exception as e:. Отредактировал сообщение, чтобы включить это.
Вам действительно стоит опубликовать:
Вот мой код, который работает:
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) = \ ? Кстати, твердый ответ.
Имя хоста может иметь несколько IP-адресов - нужно перебирать все результаты getaddrinfo. Но он должен вызываться с идентификатором протокола, чтобы пропустить UDP и подобные записи: socket.getaddrinfo(address, port, 0, 0, socket.IPPROTO_TCP).
Вы можете использовать функцию 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], чтобы получить более полезную подсказку об ошибке.
Независимо от того, установлено соединение или нет: connect_ex () всегда возвращает "0". У меня не работает
12 лет спустя для всех, у кого есть подобные проблемы.
try:
s.connect((address, '80'))
except:
alert('failed' + address, 'down')
не работает, потому что порт «80» является строкой. Ваш порт должен быть int.
try:
s.connect((address, 80))
Это должно сработать. Не уверен, почему даже лучший ответ не увидел этого.
Вы всегда должны использовать print_exc () из модуля трассировки в разделе except! что укажет на случайные ошибки.