树莓派读取MFRC522数据并发送至服务器异常问题求助
解决RFID客户端与回声服务器交互失败的问题
你正在用树莓派+MFRC522做位置参考项目,通过回声服务器测试数据传输,但客户端读取到RFID UID后,没有完成数据发送和服务器交互。从你的输出看,客户端停在了UID打印环节,说明后续的socket发送逻辑没执行到,或者有隐藏错误。我帮你梳理下代码里的几个关键问题,修改后就能正常运行了:
一、客户端代码的核心问题与修复
你的客户端代码存在缩进混乱、数据赋值错误和逻辑结构问题:
1. Socket连接与循环嵌套逻辑错误
原代码把socket连接放在了外层while True外面,内部循环嵌套逻辑混乱,导致读取到UID后,发送数据的代码可能无法触发。需要调整socket连接的位置,确保连接稳定且发送逻辑能被正确执行。
2. UID数据赋值错误
你写的data = "str(uid[0])"只是把字符串"str(uid[0])"发送出去,而不是实际读取到的UID值。需要把UID数组拼接成可传输的字符串。
3. 缩进错误导致认证后逻辑未执行
原代码中MIFAREReader.MFRC522_Read(8)等操作的缩进不对,没有放在认证成功的if块内,socket发送代码的位置也需要调整。
修改后的客户端代码
import RPi.GPIO as GPIO import MFRC522 import signal import socket HOST = '192.168.11.48' PORT = 9009 continue_reading = True # Capture SIGINT for cleanup when the script is aborted def end_read(signal, frame): global continue_reading print("Ctrl+C captured, ending read.") continue_reading = False GPIO.cleanup() # Hook the SIGINT signal.signal(signal.SIGINT, end_read) # Create an object of the class MFRC522 MIFAREReader = MFRC522.MFRC522() # Welcome message print("Welcome to the MFRC522 data read example") # 调整socket连接逻辑:确保连接稳定,异常时能捕获 try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((HOST, PORT)) print("Connected to echo server") while continue_reading: # Scan for cards (status, TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL) # If a card is found if status == MIFAREReader.MI_OK: print("Card detected") # Get the UID of the card (status, uid) = MIFAREReader.MFRC522_Anticoll() # If we have the UID, continue if status == MIFAREReader.MI_OK: # 拼接UID为字符串 uid_str = f"{uid[0]},{uid[1]},{uid[2]},{uid[3]}" print(f"Card read UID: {uid_str}") # 认证用的默认密钥 key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] # 选中扫描到的标签 MIFAREReader.MFRC522_SelectTag(uid) # 执行认证 status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 8, key, uid) # 认证成功后执行读取和发送操作 if status == MIFAREReader.MI_OK: print("Authentication success") # 读取区块8的数据(可选操作,按需保留) data_block = MIFAREReader.MFRC522_Read(8) print(f"Read block 8 data: {data_block}") # 发送UID到服务器 sock.sendall(uid_str.encode()) # 接收服务器的回声响应 server_response = sock.recv(128) print(f"Data from Echo server is [{server_response.decode()}]") MIFAREReader.MFRC522_StopCrypto1() else: print("Authentication error") except ConnectionRefusedError: print("Could not connect to server. Make sure server is running and IP/Port is correct.") except Exception as e: print(f"Client error: {e}") GPIO.cleanup()
二、服务器代码的问题与修复
你的服务器代码存在异常捕获错误和关闭逻辑缺失:
1. 异常类拼写错误
except Exceptions as e:应该是except Exception as e:(单数形式),否则会引发NameError。
2. 缺少服务器正确关闭的逻辑
捕获KeyboardInterrupt后,需要调用shutdown()和server_close()来优雅关闭服务器。
修改后的服务器代码
import socketserver HOST = '' PORT = 9009 class MyTcpHandler(socketserver.BaseRequestHandler): def handle(self): print(f"[{self.client_address[0]}] connected") try: while True: self.data = self.request.recv(1024) if not self.data: # 处理客户端主动断开的情况 print(f"[{self.client_address[0]}] disconnected") break data_str = self.data.decode().strip() if data_str == "/quit": print(f'Ended by user [{self.client_address[0]}]') return print(f'[{self.client_address[0]}] sent: {data_str}') self.request.sendall(self.data) except Exception as e: print(f"Server handler error: {e}") def runServer(): print("Starting echo server") print("If you want to close echo server, press Ctrl+C") server = None try: server = socketserver.TCPServer((HOST, PORT), MyTcpHandler) server.serve_forever() except KeyboardInterrupt: print("--- Closing server") if server: server.shutdown() server.server_close() if __name__ == "__main__": runServer()
三、测试步骤
- 先启动修改后的服务器代码。
- 再启动修改后的客户端代码。
- 把RFID卡靠近MFRC522阅读器,此时客户端应该会:
- 打印检测到卡片和UID
- 完成认证(如果卡片支持)
- 发送UID到服务器
- 接收并打印服务器的回声响应
这样就能完成完整的客户端与服务器交互了。
内容的提问来源于stack exchange,提问作者KimHG
相关产品推荐
相关产品推荐

