如何修复 python 中套接字服务器代码的线程问题

问题描述 投票:0回答:1

我正在尝试用socket python构建一个Trivia游戏,但我面临一个问题,当多个客户端尝试向服务器提交答案时,服务器大多数时候不接受客户端的所有答案,这会导致游戏中的计分问题是处理客户答案的功能,我相信这是造成问题的原因:

def handle_client_answers(server_socket, question, correct_answer):
    """Handle answers for the current question."""
    start_time = time.time()
    first_correct_time = None

    def process_answer(data, addr):
        """Process a single client's answer."""
        nonlocal first_correct_time  # Allow modification of the shared variable
        answer = data.decode().strip()
        with lock:
            if addr not in clients or clients[addr]["answered"]:
                return
            
            clients[addr]["answered"] = True

            server_socket.sendto(f"Answer Submitted: {answer}".encode(), addr)
            if answer.lower() == correct_answer.lower():
                if not first_correct_time:
                    first_correct_time = time.time()
                    clients[addr]["score"] += 10  # Full points for first correct answer
                else:
                    time_diff = time.time() - first_correct_time
                    score_multiplier = max(0.5, 1 - time_diff / 10)  # Decrease score for slower answers
                    clients[addr]["score"] += int(10 * score_multiplier)
                server_socket.sendto("Correct!".encode(), addr)
                print(f"Received answer from {clients[addr]['username']} ({addr}): {answer} - Correct!")
            else:
                server_socket.sendto("Wrong answer.".encode(), addr)
                print(f"Received answer from {clients[addr]['username']} ({addr}): {answer} - Incorrect!")


    while time.time() - start_time < 30:
        try:
            data, addr = server_socket.recvfrom(1024)
            # Start a thread to process this answer
            threading.Thread(target=process_answer, args=(data, addr), daemon=True).start()

            # Exit early if all clients have answered
            with lock:
                if all(client["answered"] for client in clients.values()):
                    break
        except socket.timeout:
            continue
    time.sleep(2)

我尝试要求 ChatGPT 解决问题,它引入了使用队列的解决方案:

from queue import Queue

answer_queue = Queue()  # Queue to hold incoming answers

def handle_client_answers(server_socket, question, correct_answer):
    """Handle answers for the current question."""
    start_time = time.time()
    first_correct_time = None

    def enqueue_answer(data, addr):
        """Add the answer to the processing queue."""
        answer_queue.put((data, addr))

    def process_answers():
        """Continuously process answers from the queue."""
        nonlocal first_correct_time
        while time.time() - start_time < 30 or not answer_queue.empty():
            try:
                data, addr = answer_queue.get(timeout=1)  # Wait for answers from the queue
                process_answer(data, addr)  # Process the answer
            except Exception as e:
                continue  # Handle timeouts or empty queue gracefully

    def process_answer(data, addr):
        """Process a single client's answer."""
        nonlocal first_correct_time  # Allow modification of the shared variable
        answer = data.decode().strip()
        with lock:
            if addr not in clients or clients[addr]["answered"]:
                return
            
            clients[addr]["answered"] = True

            server_socket.sendto(f"Answer Submitted: {answer}".encode(), addr)
            if answer.lower() == correct_answer.lower():
                if not first_correct_time:
                    first_correct_time = time.time()
                    clients[addr]["score"] += 10  # Full points for first correct answer
                else:
                    time_diff = time.time() - first_correct_time
                    score_multiplier = max(0.5, 1 - time_diff / 10)  # Decrease score for slower answers
                    clients[addr]["score"] += int(10 * score_multiplier)
                server_socket.sendto("Correct!".encode(), addr)
                print(f"Received answer from {clients[addr]['username']} ({addr}): {answer} - Correct!")
            else:
                server_socket.sendto("Wrong answer.".encode(), addr)
                print(f"Received answer from {clients[addr]['username']} ({addr}): {answer} - Incorrect!")

    # Start the worker thread to process answers from the queue
    threading.Thread(target=process_answers, daemon=True).start()

    # Collect answers during the question period
    while time.time() - start_time < 30:
        try:
            data, addr = server_socket.recvfrom(1024)
            enqueue_answer(data, addr)  # Add the answer to the queue
        except socket.timeout:
            continue

    time.sleep(2)

但问题还是一样

python multithreading sockets
1个回答
0
投票

您联系过 Python 客户支持吗?

© www.soinside.com 2019 - 2024. All rights reserved.