【问题标题】:Testing socket connection in Python在 Python 中测试套接字连接
【发布时间】:2010-09-15 16:44:52
【问题描述】:

此问题将扩展:Best way to open a socket in Python
打开套接字时,我如何测试它是否已建立,并且它没有超时,或者通常失败。

编辑: 我试过这个:

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

但即使该连接应该工作,也会调用警报函数。

【问题讨论】:

  • 您应该始终在 except 子句中使用来自 traceback 模块的 print_exc() !这将表明意外错误。

标签: python sockets


【解决方案1】:

似乎你没有捕捉到你想捕捉的异常:)

如果ssocket.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 中可以工作吗?
【解决方案2】:

您可以使用函数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”。它对我不起作用
【解决方案3】:

你真的应该发帖:

  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) = \ 分配的那个位是如何工作的?顺便说一句,可靠的答案。
  • 一个主机名可以有多个 IP 地址 - 应该循环遍历 getaddrinfo 的所有结果。但应使用协议 ID 调用它,以便跳过 UDP 和类似条目:socket.getaddrinfo(address, port, 0, 0, socket.IPPROTO_TCP)
【解决方案4】:

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

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

不起作用,因为端口“80”是一个字符串。您的端口必须是 int。

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

这应该可行。 不知道为什么即使是最好的答案也没有看到这个。

【讨论】:

  • 12 年 == 更好地使用 Context Manager TryExcept?
猜你喜欢
  • 2016-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-25
  • 2023-03-19
  • 2020-12-09
  • 2016-08-19
  • 1970-01-01
相关资源
最近更新 更多