Не удается отправить информацию нескольким указанным c клиентам в Python - PullRequest
0 голосов
/ 07 апреля 2020

Я создаю онлайн-игру в шахматы с помощью модуля python -chess. где любой человек из любой точки мира может играть друг против друга, и я почти закончил, но я застрял в этой одной проблеме. Сама игра хороша и работает, если вы играете в автономном режиме, но проблема заключается в подключении нескольких человек к совместной игре. У меня есть два сценария. Скрипт server.py, который является сервером, и скрипт Chess.py, в котором есть игра и клиент. Я пытаюсь отправить информацию от другого клиента туда и обратно, но она не работает. Из моего устранения неполадок, я не думаю, что проблема в сценарии Chess.py, а вместо этого в сценарии server.py. Всякий раз, когда я подключаюсь к серверу с двумя клиентами, чтобы играть. С клиентом player2 он делает все как положено, но с клиентом player1 он просто застревает на экране «Ожидание противника ...». Не могли бы вы, ребята, помочь мне найти проблему?

Вот код для сценария server.py:

import socket
import threading
import time
import random

HEADER = 64
SERVER = socket.gethostbyname(socket.gethostname())
PORT = 5555
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MSG = "!DISCONNECT"

one = 0
two = 0
player1 = ''
player2 = ''
player1_nick = ''
player2_nick = ''
Connected = []
Game = []

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)

def handle_client(conn, addr):
    global player1, player2, one, Connected, player1_nick, player2_nick, Game

    Connected = []
    if addr not in Connected:
        Connected.append(addr)
        msg_len = conn.recv(HEADER).decode(FORMAT)
        msg_len = int(msg_len)
        user_nick = conn.recv(msg_len).decode(FORMAT)
        if one == 0:
            player1 = addr
            player1_nick = user_nick
            one = 1

        else:
            player2 = addr
            player2_nick = user_nick

    print(f"[NEW CONNECTION] '{user_nick}' from {addr} has connected to the server.")
    while True:
        try:
            msg_len = conn.recv(HEADER).decode(FORMAT)
        except:
            print(f"[DISCONNECTION] '{user_nick}' from {addr} has disconnected")
            for i in Connected:
                if i == addr:
                    Connected.pop(i)
            break

        if msg_len:
            msg_len = int(msg_len)
            msg = conn.recv(msg_len).decode(FORMAT)
            if msg == DISCONNECT_MSG:
                print(f"[DISCONNECTION] '{user_nick}' from {addr} has disconnected")
                for i in Connected:
                    if i == addr:
                        Connected.pop(i)
                break

            for i in Game:
                if addr == Game[0]:
                    if i == Game[1]:
                        conn.send(f"{msg}".encode(FORMAT))
                elif addr == Game[1]:
                    if i == Game[0]:
                        conn.send(f"{msg}".encode(FORMAT))
    conn.close()


def start():
    global player1, player2, player1_nick, player2_nick, Game, two

    server.listen()
    print(f"[LISTENING] The server is listening on port {PORT} and on server {SERVER}")
    while True:
        conn, addr = server.accept()
        thread = threading.Thread(target=handle_client, args=(conn, addr))
        thread.start()
        time.sleep(2)
        print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
        worb = random.randint(1, 3)

        if threading.activeCount() - 1 == 2:
            Game.append(player1)
            Game.append(player2)

            print(f"\n[NEW GAME] A game has been started between '{player1_nick}' and '{player2_nick}'")
            for i in Connected:

                conn.send(f"!W:{player2_nick}".encode(FORMAT))

print("The server is starting...")
start()

А вот код для сценария Chess.py:

import chess
import chess.variant
import subprocess
import pickle
import socket

HEADER = 64
SERVER = socket.gethostbyname(socket.gethostname())
PORT = 5555
FORMAT = 'utf-8'
DISCONNECT_MSG = "!DISCONNECT"

ADDR = (SERVER, PORT)
one = 0
received_msg = 0
white_or_black = 0

user_nick = str(input("Please enter your nickname you want other people to see :  "))
input("press ENTER to connect to server...\n")

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
    client.connect(ADDR)
except ConnectionRefusedError:
    print("[ERROR] The server is currently down. Please try again later.")
    quit()

def start():
    global received_msg

    print("Waiting for an opponent...")
    try:
        received_msg = client.recv(1024).decode(FORMAT)
    except ConnectionResetError:
        print("[ERROR] The server got shutdown. Sorry for the inconvenience. Please try to join again later.")
        quit()
    game()

def send(msg):
    global received_msg
    try:
        message = msg.encode(FORMAT)
        msg_len = len(message)
        send_len = str(msg_len).encode(FORMAT)
        send_len += b' ' * (HEADER - len(send_len))
        client.send(send_len)
        client.send(message)
    except ConnectionResetError:
        print("[ERROR] The server got shutdown. Sorry for the inconvenience. Please try to join again later.")
        quit()

send(user_nick)


board = chess.Board()


mover = "WHITE"
draw_offer = 0
test = 999
move_count = 0

def game():
    global mover, draw_offer, test, move_count, received_msg, white_or_black

    subprocess.call('cls', shell=True)

    print(board)
    print("---------------")
    print("a b c d e f g h\n")
    print(f"{mover} TO MOVE\n")

    white_or_black = received_msg.split(":")[0]
    opponent_name = received_msg.split(":")[1]

    if white_or_black == "!B":
        print(f"\nYou are black and playing against '{opponent_name}'")
    else:
        print(f"\nYou are white and playing against '{opponent_name}'")
    print("\nUppercase letters are White's pieces and lowercase letters are Black's pieces.")

    while not board.is_game_over():

        if white_or_black == "!B":
            print("\nWaiting for your opponent's move...")
            try:
                board.push_san(str(client.recv(1024).decode(FORMAT)))
            except:
                print("[ERROR] The server got shutdown. Sorry for the inconvenience. Please try to join again later.")
                quit()

            if mover == "WHITE":
                mover = "BLACK"
            else:
                mover = "WHITE"

            subprocess.call('cls', shell=True)
            print(board)
            print("_______________")
            print("a b c d e f g h\n")

            if not board.is_game_over():
                print(f"{mover} TO MOVE")

            white_or_black = "!W"
            continue

        elif white_or_black == "!W":
            if test != move_count:
                if draw_offer == 1:
                    if mover == "WHITE":
                        print("\nBlack offered a draw.")
                    else:
                        print("\nWhite offered a draw.")
            try:
                move = input("\nPlease type the correct notation of the move you want to make. You can also type 'resign' to resign or 'draw' to offer/accept a draw :  ")
                board.push_san(str(move))
                if move == "resign":
                    if mover == "WHITE":
                        print(f"\nWHITE RESIGNED! BLACK WINS!")
                        send(DISCONNECT_MSG)
                        quit()
                    else:
                        print(f"\nBLACK RESIGNED! WHITE WINS!")
                        send(DISCONNECT_MSG)
                        quit()

                elif move == "draw":
                    if test == move_count:
                        print("\nDraw already offered! Make a move.")
                        continue
                    if draw_offer == 0:
                        draw_offer = 1
                        test = move_count
                        print("\nDraw offered. Make a move.")
                        continue
                    elif draw_offer == 1:
                        print("\nBOTH PLAYERS AGREED TO A DRAW")
                        send(DISCONNECT_MSG)
                        quit()
            except ValueError:
                if board.is_check():
                    print(f"\nYour king is in check!")
                    continue
                print("\nThis is an illegal move or you didn't specify which piece went to that square! Please try again.")
                continue

            subprocess.call('cls', shell=True)

            if test < move_count:
                if draw_offer == 1:
                    draw_offer = 0

            if mover == "WHITE":
                mover = "BLACK"
            else:
                mover = "WHITE"

            print(board)
            print("_______________")
            print("a b c d e f g h\n")

            if not board.is_game_over():
                print(f"{mover} TO MOVE")
            move_count += 1
            white_or_black = "!B"
            send(move)
            continue

    if mover == "WHITE":
        mover = "BLACK"
    else:
        mover = "WHITE"

    if board.is_checkmate():
        print(f"\nCHECKMATE! {mover} WINS.")
        send(DISCONNECT_MSG)
        quit()

    elif board.is_stalemate():
        print("\nIT'S A STALEMATE! IT'S A DRAW.")
        send(DISCONNECT_MSG)
        quit()
    elif board.is_insufficient_material():
        print("\nINSUFFICIENT MATERIAL! IT'S A DRAW.")
        send(DISCONNECT_MSG)
        quit()
    elif board.can_claim_draw():
        print("IT'S A DRAW.")
        send(DISCONNECT_MSG)
        quit()

if __name__ == "__main__":
    start()

Я знаю, что мой код действительно грязный, но, надеюсь, вы можете это понять.

...