`
cn.popeye
  • 浏览: 79397 次
  • 性别: Icon_minigender_1
  • 来自: ...
社区版块
存档分类
最新评论

pyxmpp2和gevent.monkey.patch_socket关于dns解析方法冲突的解决

阅读更多
最近在做xmpp相关项目。使用gevent和pyxmpp2。
多进程+gevent协程,效果还是不错。
但是打上patch_socket()就会出现问题,如果SRV域名的A记录已存在的话,将会直接解析起A记录。

举个例子:
SRV:_xmpp-client._TCP.gmail.com SRV 20 0 0 talk.l.gmail.com
A:gmail.com  A 79.18.125.19

当patch_socket()后,就会直接解析gmail.com A记录到 79.18.125.19,而不是解析talk.l.gmail.com.
gmail.com并没有5222端口提供xmpp服务,因此消息会发送失败。


阅读pyxmpp2源码和gevent文档发现:
pyxmpp2.transport._connect()中解析地址会先flag=socket.AI_NUMERICHOST 强制使用IP地址方式,失败之后才会尝试SRV解析。

而gevent.socket文档明确说明getaddrinfo会忽略flag参数:
Differs in the following ways:

raises DNSError (a subclass of gaierror) with libevent-dns error codes instead of standard socket error codes
flags argument is ignored
for IPv6, flow info and scope id are always 0
因此,patch_socket()且gmail.com存在A记录的时候,gevent.socket将会解析成功,并且返回使用。


解决方法:
import gevent
from gevent import monkey
monkey.patch_socket( dns = False, aggressive = True )

patch时加dns=False,不使用gevent.socket dns相关方法,使pyxmpp2.transport中connect函数flag=socket.AI_NUMERICHOST生效,方法包括:
__dns__ = ['getaddrinfo',
           'gethostbyname',
           'gethostbyname_ex',
           'gethostbyaddr',
           'getnameinfo',
           'getfqdn']

一般来说并不会影响patch_socket性能,毕竟只是dns解析还是使用python.socket而已。

特此分享,不走弯路。
分享到:
评论

相关推荐

    Python使用monkey.patch_all()解决协程阻塞问题

    遇到阻塞自动切换协程,程序启动时执行monkey.patch_all()解决 # 由于IO操作非常耗时,程序经常会处于等待状态 # 比如请求多个网页有时候需要等待,gevent可以自动切换协程 # 遇到阻塞自动切换协程,程序启动时...

    python-gevent-20.9.0.tar.gz

    Gevent的协程主要依赖于`gevent.hub`和`gevent.greenlet`模块,其中`gevent.greenlet`封装了Greenlet对象。 5. **使用Gevent编写协程代码** 下面是一个简单的Gevent协程示例,展示了如何并发下载多个网页: ```...

    python2-gevent-1.1.2-2.el7.x86_64.rpm

    官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装

    gevent-21.12.0-cp310-cp310-win_amd64.whl.zip

    例如,可以使用`gevent.monkey.patch_all()`来替换所有标准I/O操作。 通过以上介绍,我们可以看到gevent在Python并发编程中的重要作用。无论是构建高性能的Web服务,还是处理复杂的网络请求,gevent都能提供优雅且...

    Python-gevent轻量级进程内的并发编程

    gevent.monkey.patch_socket() ``` 需要注意的是,monkey-patching可能会带来一些副作用,比如可能导致某些库的不兼容性,因此在使用时需谨慎。 **5. gevent的事件循环和调度** gevent中的事件循环负责监控greenlet...

    python Gevent程序员指南.pdf

    - 通过 `gevent.monkey.patch_all()` 来自动修补 Python 的标准库。 - 例如,可以将标准的 socket 模块替换为 Gevent 的 socket 实现,从而使得所有基于 socket 的操作都支持异步执行。 #### 七、结论 - 通过本...

    Python Flask 并发处理笔记.md

    jobs = [gevent.spawn(fetch, url) for url in urls] gevent.joinall(jobs) ``` ##### 4.3 并发计算 在科学计算领域,如数据分析、机器学习等,通常需要进行大量的计算操作。使用并发计算可以加速计算过程,缩短...

    Python的网络编程库Gevent的安装及使用技巧

    通过本文的学习,相信您已经掌握了如何在CentOS环境下安装Gevent,以及如何运用gevent.fork和multiprocessing模块实现高效的多进程并行处理。希望这些知识能够帮助您在实际开发中构建出更加稳定可靠的高并发网络应用...

    gevent-21.12.0-cp39-cp39-win_amd64.whl.zip

    同时,由于`gevent`对某些标准库进行了猴子补丁,因此在与其他库集成时,需要确保这些库与`gevent`兼容,或者在必要时使用`gevent.monkey.patch_all()`来确保全局的协同多任务化。 总的来说,`gevent-21.12.0-cp39-...

    gevent,threads&async frameworks.pdf

    jobs = [gevent.spawn(send, 'python.org'), gevent.spawn(send, 'gevent.org')] joinall(jobs) ``` gevent 提供了标准库兼容的模块,比如 `socket`、`ssl`、`subprocess`、`thread`、`local` 和 `queue`,这意味着...

    gevent-21.12.0-cp37-cp37m-win_amd64.whl.zip

    - **网络库 monkey-patching**: gevent 可以自动“补丁”(monkey-patch)常用的网络库如 socket、http.client 等,使它们能够在 gevent 的协程环境下无缝工作。 - **性能优化**: 由于 gevent 利用协程避免了线程上...

    Python库 | gevent-20.6.2-cp36-cp36m-manylinux2010_x86_64.whl

    资源分类:Python库 所属语言:Python 资源全名:gevent-20.6.2-cp36-cp36m-manylinux2010_x86_64.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Python库 | gevent-21.1.2-cp38-cp38-win32.whl

    资源分类:Python库 所属语言:Python 资源全名:gevent-21.1.2-cp38-cp38-win32.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Python库 | gevent-1.5a4-cp35-cp35m-manylinux2010_x86_64.whl

    python库。 资源全名:gevent-1.5a4-cp35-cp35m-manylinux2010_x86_64.whl

    Python使用协程进行 IO 并发程序示例

    monkey.patch_all() # 在导入需要阻塞 的模块 之前执行, 执行脚本,修改socket 阻塞 from socket import * 创建 TCP 套接字 s = socket() s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) # 可重复使用端口号 s.bind...

    Python库 | gevent-1.1rc1-cp34-none-win_amd64.whl

    4. 转换阻塞调用: 使用`gevent.monkey.patch_all()`对标准库进行猴子补丁,将阻塞I/O转换为非阻塞。 5. 利用`gevent`的网络API: 可以直接使用`gevent.http.server`、`gevent.socket`等模块创建网络服务和客户端。 ...

    python基于gevent实现并发下载器代码实例

    本篇文章将深入探讨如何利用gevent库来实现并发下载器,通过实例代码详细解析其工作原理和实现方法。 首先,gevent是一个Python的协程库,它基于greenlet(轻量级线程)实现。greenlet是一种用户空间的线程,它们的...

    Python下载懒人图库JavaScript特效

    这是一个简单的Python脚本,主要从懒人图库下载JavaScript特效模板,在脚本中使用了gevent这个第三方...gevent.monkey.patch_socket() ''' Description:Python 爬虫抓取懒人图库的JS脚本模板 Author:admin Create-Dat

    Python库 | gevent-20.5.1-cp27-cp27mu-manylinux2010_x86_64.whl

    g2 = gevent.spawn(task2) # 主动控制事件循环 gevent.joinall([g1, g2]) ``` 在这个例子中,尽管`task1`和`task2`都有阻塞的`sleep`调用,但它们会交替执行,而不是顺序等待,从而提高了程序效率。 五、安装与...

Global site tag (gtag.js) - Google Analytics