I'm trying to run a server for a monopoly game I made.
Running it locally works fine but over the internet it breaks because of an unpickling error. Clientside:
File "/home/john/PycharmProjects/Monopoly_py/Client.py", line 6, in <module>
message, is_req = n.recv()
File "/home/john/PycharmProjects/Monopoly_py/Network.py", line 24, in recv
header = pickle.loads(header)
_pickle.UnpicklingError: invalid load key, ' '.
While on the Serverside it moves on and tries to recieve data in a line later in the script.
File "Server.py", line 152, in <module>
command = s.request("str", f"{user.name}>", user)
File "/monopoly/Server_Network.py", line 60, in request
reply = self.recv(conn)
File "/monopoly/Server_Network.py", line 15, in recv
header_size = conn.recv(2)
this happens after sending updated board in a loop like this
for user in users:
for i in range(40):
network.send("str", f"{about: 170chars of text}", user)
My network script looks like this
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.host = "ip to be filled"
self.port = "port to be filled"
self.addr = (self.host, self.port)
self.client.bind(self.addr)
def recv(self, conn):
header_size = conn.recv(2)
header_size = int.from_bytes(header_size, "little")
header = conn.recv(header_size)
if not header:
return
header = pickle.loads(header)
data = conn.recv(header["message_length"])
if header["type"] == "obj":
data = pickle.dumps(data)
elif header["type"] == "str":
data = data.decode("utf-8")
return data
def send(self, data_type, data, user):
conn = user.conn
if data_type == "obj":
array = pickle.dumps(data)
elif data_type == "str":
array = str.encode(data)
else:
return
header = {"type": data_type, "message_length": len(array), "request": False}
header_array = pickle.dumps(header)
header_length = len(header_array)
header_length = int.to_bytes(header_length, 2, "little")
conn.sendall(header_length)
conn.sendall(header_array)
conn.sendall(array)
def request(self, data_type, data, user, force_strings=True):
conn = user.conn
if data_type == "obj":
array = pickle.dumps(data)
elif data_type == "str":
array = str.encode(data)
else:
return
header = {"type": data_type, "message_length": len(array), "request": True}
header_array = pickle.dumps(header)
header_length = len(header_array)
header_length = int.to_bytes(header_length, 2, "little")
conn.sendall(header_length)
conn.sendall(header_array)
conn.sendall(array)
if force_strings:
reply = self.recv(conn)
if type(reply) != str:
print(f"{user.name} SEEMS TO USE A MODIFIED CLIENT")
reply = f"{reply}"
else:
reply = self.recv(conn)
return reply
while the client Network script looks like this
import socket
import pickle
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "ip to be filled"
self.port = "port to be filled"
self.addr = (self.server, self.port)
self.connect()
def connect(self):
try:
self.client.connect(self.addr)
print(self.recv())
print("======")
except:
pass
def recv(self):
header_size = self.client.recv(2)
header_size = int.from_bytes(header_size, "little")
header = self.client.recv(header_size)
header = pickle.loads(header)
data = self.client.recv(header["message_length"])
if header["type"] == "obj":
data = pickle.dumps(data)
elif header["type"] == "str":
data = data.decode("utf-8")
return data, header["request"]
def send(self, type, data):
if type == "obj":
array = pickle.dumps(data)
elif type == "str":
array = str.encode(data)
else:
return
header = {"type": type, "message_length": len(array)}
header_array = pickle.dumps(header)
header_length = len(header_array)
header_length = int.to_bytes(header_length, 2, "little")
self.client.sendall(header_length)
self.client.sendall(header_array)
self.client.sendall(array)
When i run it slower aka 50ms second delay it works better but still breaks after some time.