在Python中测试套接字连接

36 投票
4 回答
132066 浏览
提问于 2025-04-11 09:31

这个问题是对之前一个问题的扩展,链接在这里:在Python中打开socket的最佳方法
当我打开一个socket时,怎么才能测试它是否成功建立连接,或者说没有超时,或者一般来说没有失败呢?

编辑:
我尝试了这个:

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

但是即使连接应该成功,警报函数还是会被调用。

4 个回答

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')
11

你可以使用一个叫做 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!"
47

看起来你没有捕捉到你想要处理的那个异常呢 :)

如果 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 循环时,尽量弄清楚你捕捉到的异常是什么类型。

你可以查看 socket 模块中各种异常代表的错误类型(比如超时、无法解析地址等等),然后为每种异常写一个单独的 except 语句。这样,你就能针对不同的问题采取不同的处理方式。

撰写回答