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

树莓派读取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()

三、测试步骤

  1. 先启动修改后的服务器代码。
  2. 再启动修改后的客户端代码。
  3. 把RFID卡靠近MFRC522阅读器,此时客户端应该会:
    • 打印检测到卡片和UID
    • 完成认证(如果卡片支持)
    • 发送UID到服务器
    • 接收并打印服务器的回声响应

这样就能完成完整的客户端与服务器交互了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:21:33