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

运行sub_file.py遇AttributeError:'NoneType'无'recv'属性求修复

问题:MQTT订阅端报错 AttributeError: 'NoneType' object has no attribute 'recv'

运行pub_file.py程序可正常工作,但运行sub_file.py时出现如下错误:

AttributeError: 'NoneType' object has no attribute 'recv'

订阅端代码(sub_file.py)

import time
import paho.mqtt.client as mqtt #import the client1
import base64

broker_address="mqtt.eclipseprojects.io"

port = 1883
client = mqtt.Client("P2") #create new instance

client.connect(broker_address,port) #connect to broker

def on_message(cln, obj, msg):
  print("new message")
  data = msg.payload.decode()
  msg = str(data)
  img = msg.encode('ascii')
  with open('iris.jpg', 'wb') as fd:
    final_data = base64.b64decode(img)
    fd.write(final_data)
    fd.close()

def on_subscribe(client, userdata, mid, granted_qos):
  print("subscribe success")

client.subscribe("photo_topic_file")


client.on_subscribe = on_subscribe
print("Subscribing...")
client.loop_start()

client.on_message = on_message

client.loop_forever()

发布端代码(pub_file.py)

import paho.mqtt.client as mqtt
import base64
import time

broker_address="mqtt.eclipseprojects.io"

port = 1883
client = mqtt.Client("P1")


f = open("data.jpg", "rb")
isi_file = f.read()
convert_result_ke_base64 = base64.b64encode(isi_file)


client.connect(broker_address, port)
client.loop_start()
result = client.publish("photo_topic_file", convert_result_ke_base64)

if result[0] == 0:
    print("publish success")
else:
    print("publish failed")
    
time.sleep(5)
client.loop_stop()

错误原因及修复方案

核心问题

  • 重复启动MQTT循环:client.loop_start()(后台线程循环)和client.loop_forever()(阻塞式循环)不能同时使用,两者同时运行会引发客户端内部连接冲突,导致socket实例失效变为None,触发recv属性错误。
  • 回调绑定顺序错误:在连接、订阅操作完成后才绑定回调函数,可能错过订阅确认报文或消息推送,不符合MQTT客户端的最佳实践。
  • 变量名冲突:on_message函数中覆盖了传入的msg参数对象,会引发不必要的逻辑混乱。

修复后的订阅端代码

import time
import paho.mqtt.client as mqtt
import base64

broker_address="mqtt.eclipseprojects.io"
port = 1883
client = mqtt.Client("P2")

# 先绑定所有回调函数
def on_message(cln, obj, msg):
    print("new message")
    # 更换变量名,避免覆盖原始msg对象
    payload_data = msg.payload.decode()
    img_encoded = payload_data.encode('ascii')
    with open('iris.jpg', 'wb') as fd:
        final_data = base64.b64decode(img_encoded)
        fd.write(final_data)
        # with语句自动管理文件关闭,无需手动调用close()

def on_subscribe(client, userdata, mid, granted_qos):
    print("subscribe success")

client.on_subscribe = on_subscribe
client.on_message = on_message

# 执行连接和订阅操作
client.connect(broker_address, port)
client.subscribe("photo_topic_file")

print("Subscribing...")
# 仅启动一个阻塞式循环,维持客户端运行
client.loop_forever()

发布端代码优化(可选)

发布端存在文件未关闭的隐患,建议改用with语句管理文件:

import paho.mqtt.client as mqtt
import base64
import time

broker_address="mqtt.eclipseprojects.io"
port = 1883
client = mqtt.Client("P1")

# 用with语句自动关闭文件
with open("data.jpg", "rb") as f:
    isi_file = f.read()
    convert_result_ke_base64 = base64.b64encode(isi_file)

client.connect(broker_address, port)
client.loop_start()
result = client.publish("photo_topic_file", convert_result_ke_base64)

if result[0] == 0:
    print("publish success")
else:
    print("publish failed")
    
time.sleep(5)
client.loop_stop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:57:53