Как исправить проблему с потоками в Python для кода сервера сокетовPython

Программы на Python
Ответить
Anonymous
 Как исправить проблему с потоками в Python для кода сервера сокетов

Сообщение Anonymous »

Я пытаюсь создать игру-викторину на сокете Python, но столкнулся с проблемой: когда несколько клиентов пытаются отправить свои ответы на сервер, сервер большую часть времени не принимает все ответы клиентов. что вызывает проблему с подсчетом очков в игре, вот функция, которая обрабатывает ответы клиентов, и я считаю, что она создает проблему:

Код: Выделить всё

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)
но проблема осталась прежней
чтобы получить доступ к полному коду, посетите этот github: https://github.com/moe-the- козел/1-ый-сетевой-проект

Подробнее здесь: https://stackoverflow.com/questions/792 ... erver-code
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»