Micropython中socket.getaddrinfo使用本地DNS时触发ECONNABORTED错误
ESP8266 MicroPython socket.getaddrinfo() 本地DNS触发ECONNABORTED错误排查方案
针对ESP8266(ESP-12F)上MicroPython调用socket.getaddrinfo()时,使用本地DNS服务器触发OS Error: [Error 103] ECONNABORTED错误、公网DNS正常的问题,可从以下方向排查解决:
调整DNS超时设置
MicroPython默认DNS查询超时可能较短,本地DNS递归查询上游ISP DNS耗时较长时会触发连接中止。尝试手动指定DNS并延长超时:import socket # 手动设置本地DNS服务器 socket.dns_server("192.168.X.X") # 设置DNS超时为5秒(部分MicroPython版本支持,单位毫秒) socket.dns_timeout(5000) host = 'google.com' port = 443 addr_info = socket.getaddrinfo(host, port) print('addr_info:', addr_info)验证本地DNS报文兼容性
本地DNS返回的UDP报文格式可能与MicroPython解析器不兼容。用dig工具测试本地DNS响应:dig @192.168.X.X google.com检查响应是否符合标准DNS格式,重点排查是否存在过长响应、非标准记录类型等异常情况。
升级MicroPython固件
旧版本固件的DNS解析逻辑可能存在bug,尤其是针对本地DNS的场景。下载官方最新稳定版ESP8266 MicroPython固件,重新烧录设备后测试。绕过getaddrinfo,手动实现DNS查询
如果确认是内置getaddrinfo的底层问题,可直接通过UDP套接字实现简单DNS查询,再传入IP调用getaddrinfo:import socket def dns_query(host, dns_server): # 构建A记录DNS查询报文 query = b'\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00' for part in host.split('.'): query += bytes([len(part)]) + part.encode() query += b'\x00\x00\x01\x00\x01' sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(5) sock.sendto(query, (dns_server, 53)) data, _ = sock.recvfrom(512) sock.close() # 解析返回的IP地址 if len(data) >= 44: ip = '.'.join(map(str, data[-4:])) return ip return None host = 'google.com' dns = '192.168.X.X' ip = dns_query(host, dns) if ip: addr_info = socket.getaddrinfo(ip, 443) print('addr_info:', addr_info) else: print('DNS查询失败')检查本地网络规则
排查路由器是否针对ESP8266的IP设置了UDP 53端口拦截规则,或开启了DNS过滤功能导致请求被中止。即使其他设备正常,ESP8266可能被单独限制。
内容的提问来源于stack exchange,提问作者Richard Fall
相关产品推荐
相关产品推荐

