简体   繁体   English

pickle.loads() 的问题 - 输入不足

[英]Problem with pickle.loads() - ran out of input

I'm trying to make a small multiplayer game and thus need to send objects.我正在尝试制作一个小型多人游戏,因此需要发送对象。 Have created server and client and everything is working for sending bytes eg (str("").encode(utf-8)) .已经创建了服务器和客户端,一切都在发送字节,例如(str("").encode(utf-8))

But when I tried to use pickle I've started bumping into issues.但是当我尝试使用泡菜时,我开始遇到问题。 Have I made any mistakes below?我在下面犯了任何错误吗?

Server.py:服务器.py:

import socket
import threading
import pickle

HEADER = 8          #Contains info about incoming msg SIZE! first 8 bytes contains size
FORMAT = "utf-8"
PORT = 5558
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
DISCONNECT_MSG = "!Disconnect"

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

def handle_client(client_socket, client_addr):
    print(f"[NEW CONNECTION] {client_addr} connected!")

    while True:
        try:
            msg = pickle.loads(client_socket.recv(2048))
            print(f"[RECEIVED] {client_addr} - {msg}")
            if msg == DISCONNECT_MSG:
                print(f"[DISCONNECTED] client {client_addr} has disconnected")
                client_socket.close()
                return False
        except socket.error as e:
            print(e)

def start_server(server):
    server.listen()
    print("[STARTED] server is online!")

    while True:
        client_socket, client_addr = server.accept()
        thread = threading.Thread(target=handle_client, args=(client_socket, client_addr))
        thread.start()
        print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")

print("[STARTING] server is starting...")
start_server(server_socket)

Client.py客户端.py

import socket
import pickle

HEADER = 8
FORMAT = "utf-8"
PORT = 5558
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
DISCONNECT_MSG = "!Disconnect"

class Client:

    def __init__(self):
        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def connect_to_server(self, server_address):
        """
        :param server_address: tuple(IP, PORT)
        :return:
        """
        self.get_client_socket().connect(server_address)

    def get_client_socket(self):
        return self.client_socket

    def send_object(self, object):
            msg = pickle.dumps(object)
            self.get_client_socket().sendall(msg)

client = Client()
client.connect_to_server(ADDR)
d = "1"
client.send_object(d)
#client.send_object(DISCONNECT_MSG)

I've also tried to put while loop into send_object() but then after couple of successful receivements I get:我也尝试将 while 循环放入 send_object() 但在几次成功接收后我得到:

msg = pickle.loads(client_socket.recv(2048))
_pickle.UnpicklingError: invalid load key, '\x00'.

After some research it appears that before trying to unpickle an object you first need to check if received message is not None.经过一些研究,似乎在尝试解开 object 之前,您首先需要检查收到的消息是否不是 None。 Because server is constantly trying to receive message from client, but that is another issue.因为服务器不断尝试从客户端接收消息,但这是另一个问题。 Code modification in server.py: server.py 中的代码修改:

def handle_client(client_socket, client_addr):
    print(f"[NEW CONNECTION] {client_addr} connected!")

        while True:
        try:
            msg = client_socket.recv(2048)
            if msg:
                new_msg = pickle.loads(msg[HEADER:])
                print(f"[RECEIVED] {client_addr} - {new_msg}")
                if msg == DISCONNECT_MSG:
                    print(f"[DISCONNECTED] client {client_addr} has disconnected")
                    client_socket.close()
                    return False
        except socket.error as e:
            print(e)

Note -> Until DISCONNECT message is not sent from client it will use much processor time (issue mentioned above)注意 -> 直到 DISCONNECT 消息没有从客户端发送,它将使用很多处理器时间(上面提到的问题)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM