几天前,我编写了一个小游戏来学习套接字和线程。当我在 Windows 上运行我的游戏服务器和客户端时,它运行良好,但是当我将服务器文件移动到我的测试服务器时,它给了我这个 pickle 错误:
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "server.py", line 46, in handle_client
obj = pickle.loads(conn.recv(obj_length))
_pickle.UnpicklingError: invalid load key, ' '.
可能是什么问题呢?
整个游戏文件:---------------------------------------------- ----------------------------------
可能有帮助的代码:
服务器.py:
import socket
import threading
import pickle
import time
import random
import ast
#-------------------------------------------------------------------------
class Server():
def __init__(self):
self.HEADER = 2048
self.PORT = 6000
self.SERVER = "ip"
self.ADDR = (self.SERVER, self.PORT)
self.FORMAT = 'utf-8'
self.DISCONNECT_MESSAGE = "!DISCONNECT"
self.ROLES = ["Mafya", "Mafya", "Köylü", "Doktor","Gözcü"]
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind(self.ADDR)
#---------------------------------------------------------------------------------------------
self.names = list()
self.addresses = list()
self.lobby_dict = dict()
self.game_dict = dict()
self.ready_list = list()
self.alive_list = list()
self.vote = list()
self.kill_vote = list()
self.who_voted = list()
self.ready_for_day = list()
self.protected = None
def handle_client(self, conn, addr):
try:
if addr[0] not in self.addresses:
print(f"[NEW CONNECTION] {addr[0]} connected.")
self.addresses.append(addr[0])
connected = True
while connected:
obj_length = conn.recv(self.HEADER).decode(self.FORMAT)
if obj_length:
obj_length = int(obj_length)
obj = pickle.loads(conn.recv(obj_length))
if obj == self.DISCONNECT_MESSAGE:
connected = False
print(f"[DISCONNECTED] {addr[0]} disconnected.")
elif "?ONLINE" in obj:
lobby_id = obj.split(":")[1]
conn.send(pickle.dumps(self.lobby_dict[lobby_id]["Players"]))
elif "!NEWLOBBY" in obj:
splitted_obj = obj.split(":")
lobby_id = splitted_obj[1]
admin = splitted_obj[2]
capacity = splitted_obj[3]
self.lobby_dict[lobby_id] = {"Players":[admin],"Capacity":capacity}
elif "!JOINLOBBY" in obj:
splitted_obj = obj.split(":")
lobby_id = splitted_obj[1]
name = splitted_obj[2]
if lobby_id in self.lobby_dict.keys():
self.lobby_dict[lobby_id]["Players"].append(name)
conn.send(pickle.dumps(f"True:{self.lobby_dict[lobby_id]['Capacity']}"))
else:
conn.send(pickle.dumps("False"))
elif "?ALIVE" in obj:
conn.send(pickle.dumps(self.alive_list))
#-----------------------------------------------------------------------------------------------
#Game commands:
elif "!NAME" in obj:
name = obj.split(":")[1]
self.names.append(name)
elif "!ALIVE" in obj:
conn.send(pickle.dumps(self.names))
elif "!READY" in obj:
ready_player = obj.split(":")[1]
self.ready_list.append(ready_player)
elif "!SHUFFLE" in obj:
if len(self.ready_list) == len(self.names):
temp = self.ROLES
if len(self.names) > len(self.ROLES):
for i in range(0,len(self.names) - len(self.ROLES)):
temp.append("Köylü")
random.shuffle(temp)
for i in range(len(self.names)):
self.game_dict[self.names[i]] = temp[i]
conn.send(pickle.dumps(f"True/{self.game_dict}"))
with open("shuffled_roles.txt", "w", encoding="utf-8") as file:
file.write(str(self.game_dict))
print(f"[SHUFFLED LIST] {self.game_dict}")
else:
conn.send(pickle.dumps("False"))
elif "!ROLES" in obj:
if len(self.ready_list) == len(self.names):
with open("shuffled_roles.txt", "r", encoding="utf-8") as file:
line = file.readline()
self.game_dict = ast.literal_eval(line)
conn.send(pickle.dumps(f"True/{self.game_dict}"))
else:
conn.send(pickle.dumps("False"))
elif "!VOTE" in obj:
voted_player = obj.split(":")[1]
who = obj.split(":")[2] + ": " + voted_player
self.who_voted.append(who)
self.vote.append(voted_player)
elif "!VRESULTS" in obj:
conn.send(pickle.dumps(self.vote))
conn.send(pickle.dumps(self.who_voted))
elif "!VCLEAN" in obj:
self.vote = []
self.who_voted = []
elif "!PROTECTED" in obj:
protected = obj.split(":")[1]
self.protected = obj
elif "!NIGHT_KILL" in obj:
kill = obj.split(":")[1]
self.kill_vote.append(kill)
elif "!NKRESULTS" in obj:
nk_results = self.kill_vote
nk_protected = self.protected
if len(nk_results) == 1:
if nk_results[0] != nk_protected:
conn.send(pickle.dumps(nk_results[0]))
elif len(nk_results) == 2:
if nk_results[0] == nk_results[1]:
if nk_results[0] != nk_protected and nk_results[0] != "None":
conn.send(pickle.dumps(nk_results[0]))
elif nk_results[0] == "None" and nk_results[1] != "None":
conn.send(pickle.dumps(nk_results[1]))
elif nk_results[1] == "None" and nk_results[0] != "None":
conn.send(pickle.dumps(nk_results[0]))
else:
conn.send(pickle.dumps(None))
else:
conn.send(pickle.dumps(None))
elif "!NKCLEAN" in obj:
self.protected = "None"
self.kill_vote = []
elif "!RFORDAY" in obj:
rplayer = obj.split(":")[1]
self.ready_for_day.append(rplayer)
elif "!RFDLIST" in obj:
conn.send(pickle.dumps(self.ready_for_day))
elif "!RFDCLEAN" in obj:
self.ready_for_day = list()
else:
print(f"[{addr}] {obj}") #İsimler Buradan -> addr
except ConnectionResetError:
print(f"[CONNECTION] {addr} Connection reset exception has been handled.")
finally:
conn.close()
def start(self):
print("[STARTING] Server is starting...")
self.server.listen()
print("[LISTENING] Server is listening on {}".format(self.SERVER))
while True:
conn, addr = self.server.accept()
thread = threading.Thread(target=self.handle_client, args=(conn, addr))
thread.start()
if __name__ == "__main__":
server = Server()
server.start()
应用程序.py:
import sys
import os
import time
import random
import socket
import threading
import pickle
class Config():
def __init__(self):
self.HEADER = 2048
self.PORT = 6000
self.SERVER = "ip" #socket.gethostbyname(socket.gethostname())
self.ADDR = (self.SERVER, self.PORT)
self.FORMAT = 'utf-8'
self.DISCONNECT_MESSAGE = "!DISCONNECT"
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.menuText = """
░██╗░░░░░░░██╗██╗░██████╗███████╗ ████████╗░█████╗░░██╗░░░░░░░██╗███╗░░██╗
░██║░░██╗░░██║██║██╔════╝██╔════╝ ╚══██╔══╝██╔══██╗░██║░░██╗░░██║████╗░██║
░╚██╗████╗██╔╝██║╚█████╗░█████╗░░ ░░░██║░░░██║░░██║░╚██╗████╗██╔╝██╔██╗██║
░░████╔═████║░██║░╚═══██╗██╔══╝░░ ░░░██║░░░██║░░██║░░████╔═████║░██║╚████║
░░╚██╔╝░╚██╔╝░██║██████╔╝███████╗ ░░░██║░░░╚█████╔╝░░╚██╔╝░╚██╔╝░██║░╚███║
░░░╚═╝░░░╚═╝░░╚═╝╚═════╝░╚══════╝ ░░░╚═╝░░░░╚════╝░░░░╚═╝░░░╚═╝░░╚═╝░░╚══╝
"""
class Client(Config):
def __init__(self):
super().__init__()
self.client.connect(self.ADDR)
self.admin = None
def send(self, obj):
obj = pickle.dumps(obj)
obj_length = len(obj)
send_length = str(obj_length).encode(self.FORMAT)
send_length += b' ' * (self.HEADER - len(send_length))
self.client.send(send_length)
self.client.send(obj)
def messenger(self):
while True:
msg = input("Mesaj: ")
self.send(msg)
class Menu(Client):
def __init__(self):
super().__init__()
class MainMenu(Menu):
def __init__(self, player_name):
super().__init__()
self.player_name = player_name
def printMainMenu(self, game_is_on = False):
print("\n" * 7 + self.menuText)
time.sleep(2)
os.system("cls")
print(self.menuText)
print("""
1. Yeni Oyun Oluştur
2. Oyuna Katıl
""")
class Lobby(Menu):
def __init__(self):
super().__init__()
def lobbyMenu(self):
name_send = f"!NAME:{self.player_name}"
self.send(name_send)
os.system("cls")
print(self.menuText)
print(f"Lobby ID: {self.id}")
self.send(f"?ONLINE:{self.id}")
self.online_list = pickle.loads(self.client.recv(2048))
temp_list = self.online_list
sys.stdout.write("Aktif Oyuncular:| ")
for i in self.online_list:
sys.stdout.write(f"{i} | ")
sys.stdout.flush()
while not self.game_started:
time.sleep(1)
self.send("?ONLINE:" + str(self.id))
self.online_list = pickle.loads(self.client.recv(2048))
if temp_list != self.online_list:
sys.stdout.write("\rAktif Oyuncular:| ")
for i in self.online_list:
sys.stdout.write(f"{i} | ")
sys.stdout.flush()
temp_list = self.online_list
if len(self.online_list) == self.capacity:
self.game_started = True
class CreateLobby(Lobby):
def __init__(self, capacity, player_name, admin):
super().__init__()
self.player_name = player_name
self.admin = admin
self.id = random.randint(100000,999999)
self.capacity = int(capacity)
self.game_started = False
self.send(f"!NEWLOBBY:{self.id}:{self.player_name}:{self.capacity}")
self.lobbyMenu()
class JoinLobby(Lobby):
def __init__(self, id, player_name):
super().__init__()
self.id = id
self.player_name = player_name
self.game_started = False
self.lobby_joiner()
def lobby_joiner(self):
self.send(f"!JOINLOBBY:{self.id}:{self.player_name}")
bool_obj = pickle.loads(self.client.recv(2048))
while bool_obj == "False":
print("Bu ID'ye ait lobby bulunmamaktadır.")
self.id = input(" Lobby ID: ")
self.send(f"!JOINLOBBY:{self.id}:{self.player_name}")
bool_obj = pickle.loads(self.client.recv(2048))
self.capacity = int(bool_obj.split(":")[1])
self.lobbyMenu()
#-------------------------------------------------------------------------------------------------------------