您的位置:

解决Exception("Requested socket family %d but got %d" % (family, resolved_family))在tornado出现报错

  发布时间:2025-01-03 08:54:02
解决 Tornado 框架中出现请求的 socket 类型与实际获取到的 socket 类型不匹配的问题,通过明确指定 socket 类型来保持一致性。示例代码中通过设置 family 参数或指定使用 IPv4 地址族来避免异常。

问题原因

出现 Exception("Requested socket family %d but got %d" % (family, resolved_family)) 这个错误的原因通常是由于在使用 Tornado 框架时,尝试建立网络连接时请求的 socket 类型与实际获取到的 socket 类型不匹配导致的。这个问题通常出现在 Tornado 的异步网络编程中,例如在异步 HTTP 客户端或服务器中。 造成这个错误的主要原因是通常在初始化网络连接时,请求的 socket 类型与实际获取到的 socket 类型不一致。比如请求了 IPv4 地址族(AF_INET),但实际获取到的是 IPv6 地址族(AF_INET6)。这种情况可能是由于 DNS 解析返回了不同类型的 IP 地址引起的。 为了解决这个问题,可以通过指定 socket 类型来确保请求的 socket 类型与实际获取到的 socket 类型一致。比如明确指定使用 IPv4 地址族(AF_INET)或 IPv6 地址族(AF_INET6),以确保一致性。 总结一下,出现 Exception("Requested socket family %d but got %d" 错误的主要原因是请求的 socket 类型与实际获取到的 socket 类型不匹配,解决方法是明确指定使用特定的 socket 类型来保持一致。

解决方案

出现异常 "Requested socket family %d but got %d" 是因为 Tornado 在解析主机名时,返回的 IP 地址协议版本与期望的不一致。这个问题通常出现在 IPv6 和 IPv4 混合环境中,导致 Socket 地址的协议版本不匹配。 要解决这个问题,可以通过设置 Tornado 的 family 参数来指定期望的协议版本。在创建 HTTP 请求时,可以通过传递 family=socket.AF_UNSPEC 参数来允许支持 IPv4 和 IPv6。示例代码如下:


import tornado.httpclient
import socket

http_client = tornado.httpclient.HTTPClient()
try:
    response = http_client.fetch("http://www.example.com", family=socket.AF_UNSPEC)
    print(response.body)
except Exception as e:
    print("Error: %s" % e)
http_client.close()

在创建 HTTP 请求时,通过将 family 设置为 socket.AF_UNSPEC,可以告诉 Tornado 允许使用 IPv4 或 IPv6 地址。这样可以避免出现 "Requested socket family %d but got %d" 异常。

具体例子

在Tornado中出现Exception("Requested socket family %d but got %d" % (family, resolved_family))这个错误通常是由于请求的socket家族与实际获取的家族不匹配而导致的。要正确使用Tornado,需要在创建HTTP服务器实例时,明确指定socket家族(IPv4或IPv6),以确保请求的socket家族与实际获取的家族匹配。 以下是一个正确使用Tornado的示例代码:


import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, World")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ], xheaders=True)

if __name__ == "__main__":
    app = make_app()
    app.listen(8888, address='127.0.0.1')  # 明确指定使用IPv4地址
    tornado.ioloop.IOLoop.current().start()

在上面的示例中,我们通过指定address='127.0.0.1'明确告知Tornado在绑定HTTP服务器时使用IPv4地址。这样可以避免出现请求的socket家族与实际获取的家族不匹配的错误。 通过以上方式,我们可以正确地使用Tornado,并避免出现Exception("Requested socket family %d but got %d" % (family, resolved_family))这个错误。