You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyBluez调用accept()报[Errno 77]错误如何解决

问题根因

[Errno 77] File descriptor in bad state 报错的核心原因是混淆了RFCOMM蓝牙套接字的客户端、服务端角色的API调用逻辑:

  • 调用s.connect()后,当前套接字会被初始化为主动发起连接的客户端套接字,仅用于和远端设备直接通信,不存在监听等待新连接的状态,无法调用accept()方法。
  • accept()是服务端监听套接字专属方法,只有套接字完成本地端口绑定、开启监听,进入等待接入状态后,才能合法调用accept()接收新的连接请求。
分场景正确实现

场景1:树莓派作为客户端主动连接手机

该场景不需要调用accept(),connect()执行成功后,直接使用当前套接字即可和手机收发数据,示例代码:

import bluetooth

# 替换为手机的实际蓝牙MAC地址
target_mac = "XX:XX:XX:XX:XX:XX"
port = 19

s = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
s.connect((target_mac, port))

# 连接建立后直接通过s收发数据
s.send("hello from raspberry pi".encode("utf-8"))
data = s.recv(1024)
print(f"收到手机返回数据: {data.decode('utf-8')}")

s.close()

注意:该模式需要手机端提前在对应RFCOMM端口开启蓝牙服务监听,否则会触发连接拒绝错误。

场景2:树莓派作为服务端等待手机主动连接

该场景才需要使用accept(),完整流程为创建套接字、绑定本地端口、开启监听、等待连接,示例代码:

import bluetooth

port = 19
# 创建服务端套接字
server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
# 绑定本地蓝牙适配器的对应端口
server_sock.bind(("", port))
# 开启监听,设置最大排队连接数为1
server_sock.listen(1)

print(f"蓝牙服务已启动,在RFCOMM端口{port}等待设备连接...")
# 等待客户端接入,此处调用accept为合法操作
client_sock, client_addr = server_sock.accept()
print(f"已接入设备地址: {client_addr}")

# 通过返回的client_sock和连接的手机收发数据
client_sock.send("hello from raspberry pi server".encode("utf-8"))
data = client_sock.recv(1024)
print(f"收到手机数据: {data.decode('utf-8')}")

client_sock.close()
server_sock.close()
额外排查点

调整套接字逻辑后如果仍然报错,按以下顺序排查:

  • 先通过bluetoothctl确认树莓派蓝牙已启动、可被发现,且已经和目标手机完成配对
  • 确认使用的RFCOMM端口和对端开放的端口一致:通用蓝牙串口(SPP)服务默认端口为1,使用19这类自定义端口需要提前确认对端对应端口已开启监听
  • 确认运行代码的用户具备蓝牙操作权限,可先通过sudo执行代码排除权限干扰

内容的提问来源于stack exchange,提问作者Mihai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 17:42:25