使用pigpio连接树莓派时能否设置连接超时属性?
使用pigpio远程连接树莓派时,发现其没有内置方法设置连接超时——即指定尝试连接多久后中止操作。
现有代码如下:
def _connect_to_linked_pi(self): try: if self.linked_pi is None: pi = pigpio.pi(device_ip, PIGPIO_PORT) sock = pi.sl.s sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 3) except Exception as e: print(f"Error trying to connect -> {e}")
当前问题:即使无法连接到目标端,仍会创建连接对象,首次连接失败需等待30秒才会输出如下警告,后续尝试也需等待3秒:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Can't connect to pigpio at 192.168.108.1(8888)Did you start the pigpio daemon? E.g. sudo pigpiod
Did you specify the correct Pi host/port in the environment
variables PIGPIO_ADDR/PIGPIO_PORT?
E.g. export PIGPIO_ADDR=soft, export PIGPIO_PORT=8888Did you specify the correct Pi host/port in the
pigpio.pi() function? E.g. pigpio.pi('soft', 8888)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
需求:设置连接超时,避免长时间等待,并能捕获该特定错误。
pigpio本身未提供连接超时的内置参数,但可以通过手动创建并配置socket,再将其绑定到pigpio实例的方式实现超时控制,具体实现如下:
import socket import pigpio def _connect_to_linked_pi(self): self.linked_pi = None try: # 创建TCP socket并设置连接超时 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) # 自定义超时时间,示例为5秒 # 配置TCP保活参数(与原代码保持一致) sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 3) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 1) # 主动连接目标树莓派的pigpio端口 sock.connect((device_ip, PIGPIO_PORT)) # 初始化pigpio实例并绑定已连接的socket pi = pigpio.pi() pi.set_sock(sock) # 验证连接状态 if not pi.connected: raise ConnectionError("pigpio connection initialization failed") self.linked_pi = pi except socket.timeout: print("连接超时:未能在指定时间内连接到目标设备") except ConnectionRefusedError: print("连接被拒绝:目标设备未启动pigpio守护进程,或IP/端口配置错误") except Exception as e: print(f"连接出错:{str(e)}")
核心要点:
- 手动控制连接超时:通过
sock.settimeout()直接设置连接阶段的超时时间,替代pigpio默认的30秒/3秒等待 - 提前捕获特定异常:在socket连接阶段就能捕获
socket.timeout、ConnectionRefusedError等明确错误,无需等待pigpio的警告输出 - 绑定socket到pigpio:使用
pi.set_sock()将已连接的socket交给pigpio实例,后续可正常调用所有pigpio方法 - 验证连接有效性:通过
pi.connected属性确认pigpio是否成功初始化连接,避免后续操作出错
内容的提问来源于stack exchange,提问作者RedRum69

