29

这个问题将扩展:在 Python 中打开套接字的最佳方法打开套接字
时,我如何测试它是否已建立,并且它没有超时,或者通常失败。

编辑:我试过这个:

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

但是即使该连接应该有效,也会调用警报功能。

4

4 回答 4

43

似乎你没有抓住你想在那里抓住的例外:)

如果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为它们中的每一个单独声明 - 这样您就可以对不同类型的错误做出不同的反应问题。

于 2008-10-07T06:46:53.403 回答
10

您可以使用函数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!"
于 2013-12-12T11:12:04.887 回答
6

你真的应该发布:

  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')
于 2008-10-07T08:48:00.850 回答
1

对于任何有类似问题的人来说,12 年后。

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

不起作用,因为端口 '80' 是一个字符串。您的端口需要是 int。

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

这应该有效。不知道为什么即使是最好的答案也没有看到这一点。

于 2020-04-01T14:06:01.647 回答