运行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_
相关产品推荐
相关产品推荐

