如何在SMTP库中添加IPv6选项?
当我试图使用IPv6连接到SMTP时,我得到了以下错误:
smtpserver = smtplib.SMTP("smtp.gmail.com", 587, source_address=('2a00:xxxx:5::1e7', 80, 0, 0))错误:TypeError: AF_INET address must be a pair (host, port)
这意味着smtplib.py不支持IPv6
我找到一篇关于"https://bugs.python.org/issue3461“的文章。我试图将这个补丁添加到我的smtplib.py中,但是它没有工作
有人能帮我做这个吗?
发布于 2021-04-18 14:47:22
...Source_address=(‘2a00:xxxx:5:1e7’,80,
错误信息具有误导性。在Linux上执行strace显示,它实际上试图绑定到给定的IP和端口,但是失败了--然后发出这条误导性错误消息。失败的原因可能有多种,但典型的情况可能是没有权限向端口出价(像这里所做的那样绑定到端口80需要根权限),或者端口已经被另一个套接字所使用(端口80通常用于web服务器)。
通常,最好只指定IP地址并将端口保留为0。这样,它将使用给定的IP地址作为源IP,但选择一个随机(临时)端口作为源端口。
我找到了一篇关于"https://bugs.python.org/issue3461“的文章
这是不相关的。它只涉及在SMTP对话框中显示在EHLO命令中的发送方。如果这是一个问题,只需给出与local_hostname参数一起使用的值。
发布于 2022-02-07 03:16:29
Python3的socket.create_connection获得可连接的目标地址的第一个DNS解析项(这是在Python设计中记录为不稳定的行为)。
https://github.com/python/cpython/blob/fdcb675e/Lib/socket.py#L824
CPython实现_socket.connect在创建时看到套接字的地址家族与另一时间的地址家族之间的不匹配会引发问题。
https://github.com/python/cpython/blob/1aa6be0/Modules/socketmodule.c#L1807
仔细观察socket.create_connection,我猜source_address参数无法控制用于目标的地址系列。套接字对象sock是在create_connection中使用解析目标地址的地址系列创建的。然后使用source_address通过调用sock.bind(source_address)来指定对象的源。现在看来,如果解析的目标是IPv4,但source_address是IPv6,那么会抛出错误吗?
作为一种可能的修复方法,不会对socket.create_connection进行猴子补丁,我可以想象调用者没有在目标地址中提供一个符号主机名,而是首先将主机名解析为A或AAAA条目,这取决于所需的家族。调用方提供数字记录作为目标地址。源地址的家庭也应与所期望的家庭相一致。
换句话说,调用方可以使用socket.getaddrinfo查找所需的目标地址。其他调用者,如request库的用户,也可以使用相同的想法连接socket.create_connection。
https://docs.python.org/3/library/socket.html#socket.getaddrinfo
https://stackoverflow.com/questions/67148261
复制相似问题